首页 > 解决方案 > 如何从子组件的输入字段中呈现更新的值

问题描述

我有一个 react js 父组件。当它被调用时,会打开一个显示用户记录的欢迎页面。此页面上还有一个注册按钮。单击注册按钮时会打开一个对话框,其中询问用户详细信息。我的要求是数据应该从对话框流到欢迎页面(以及之前呈现的用户)。它应该包括更新的记录。我尝试使用回调函数。

我的 Todo 组件:

import React, { Component } from 'react';
import './Todo.css';
import FormDialog from './FormDialog';
import Dialog from '@material-ui/core/Dialog';
import { thisExpression } from '@babel/types';

class Todo extends Component {
  state = {
    edit: false,
    id: null,
    view: false,
    students: [
      { id: 1, name: 'Wasif', age: 21, email: 'wasif@email.com' },
      { id: 2, name: 'Ali', age: 19, email: 'ali@email.com' },
      { id: 3, name: 'Saad', age: 16, email: 'saad@email.com' },
      { id: 4, name: 'Asad', age: 25, email: 'asad@email.com' },
      { id: 5, name: 'kiwi', age: 20, email: 'kiwi@email.com' }
    ]
  };

  onDeleteHandle() {
    let id = arguments[0];
    this.setState({
      students: this.state.students.filter(item => {
        if (item.id !== id) {
          return item;
        }
      })
    });
  }

  onUpdateHandle(event) {
    event.preventDefault();
    this.setState({
      students: this.state.students.map(item => {
        if (item.id === this.state.id) {
          item['id'] = event.target.updatedItem.value;
          item['name'] = event.target.updatedItem1.value;
          item['age'] = event.target.updatedItem2.value;
          item['email'] = event.target.updatedItem3.value;
        }
        return item;
      })
    });
    this.setState({ edit: false });
  }

  signUpDialog() {
    this.setState({ view: true });
  }

  renderEditForm() {
    if (this.state.edit) {
      return (
        <form onSubmit={this.onUpdateHandle.bind(this)}>
          <input type="text" name="updatedItem" className="item" defaultValue={this.state.id} />
          <input type="text" name="updatedItem1" className="item" defaultValue={this.state.name} />
          <input type="text" name="updatedItem2" className="item" defaultValue={this.state.age} />
          <input type="text" name="updatedItem3" className="item" defaultValue={this.state.email} />
          <button className="update-add-item">Update</button>
        </form>
      );
    }
  }

  onEditHandle(event) {
    this.setState({ edit: true, id: arguments[0], name: arguments[1], age: arguments[2], email: arguments[3] });
  }

  onSubmitHandle(p1, p2, p3, p4) {
    this.setState({ students: [...this.state.students, { id: { p1 }, name: { p2 }, age: { p3 }, email: { p4 } }] });
  }

  render() {
    return (
      <div style={{ width: '500px', background: 'beige' }}>
        <form>
          <button onClick={this.signUpDialog.bind(this)}>Sign-UP</button>
          {this.state.view ? <FormDialog details={this.onSubmitHandle} /> : null}
          <table>
            {this.state.students.map(abc => (
              <tr>
                <td>{abc.id}</td>
                <td>{abc.name}</td>
                <td>{abc.age}</td>
                <td>{abc.email}</td>
                <td>
                  <button onClick={this.onDeleteHandle.bind(this, abc.id)}>Delete</button>
                </td>
                <button onClick={this.onEditHandle.bind(this, abc.id, abc.name, abc.age, abc.email)}>Edit</button>
              </tr>
            ))}
          </table>
        </form>{' '}
      </div>
    );
  }
}

export default Todo;

以下是我的子组件,它有一个对话框。

import React, { Component } from 'react';

import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';

class FormDialog extends Component {
  constructor(props) {
    super(props);
    this.state = { edit: false, view: true };
    this.onSubmitForm = this.onSubmitForm.bind(this);
  }
  handleClose() {
    this.setState({ view: !this.state.view });
  }
  onDeleteHandle() {
    let id = arguments[0];
    this.setState({
      students: this.state.students.filter(item => {
        if (item.id !== id) {
          return item;
        }
      })
    });
  }

  onEditHandle(event) {
    this.setState({ edit: true, id: arguments[0], name: arguments[1], age: arguments[2], email: arguments[3] });
  }
  onUpdateHandle(event) {
    event.preventDefault();
    this.setState({
      students: this.state.students.map(item => {
        if (item.id === this.state.id) {
          item['id'] = event.target.updatedItem.value;
          item['name'] = event.target.updatedItem1.value;
          item['age'] = event.target.updatedItem2.value;
          item['email'] = event.target.updatedItem3.value;
        }
        return item;
      })
    });
    this.setState({ edit: false });
  }

  renderEditForm() {
    if (this.state.edit) {
      return (
        <form onSubmit={this.onUpdateHandle.bind(this)}>
          <input type="text" name="updatedItem" className="item" defaultValue={this.state.id} />
          <input type="text" name="updatedItem1" className="item" defaultValue={this.state.name} />
          <input type="text" name="updatedItem2" className="item" defaultValue={this.state.age} />
          <input type="text" name="updatedItem3" className="item" defaultValue={this.state.email} />
          <button className="update-add-item">Update</button>
        </form>
      );
    }
  }

  onSubmitForm(event) {
    this.props.details(
      event.target.id.value,
      event.target.item.value,
      event.target.xyz.value,
      event.target.email.value
    );
  }

  render() {
    return (
      <div>
        <Dialog fullWidth open={this.state.view} onClose={this.handleClose.bind(this)}>
          <DialogTitle>Sign Up Provide Details</DialogTitle>
          <DialogContent>
            {this.renderEditForm()}

            <DialogContentText>
              <div>
                <form onSubmit={e => this.onSubmitForm(e)}>
                  <label>ID</label>
                  <input type="number" name="id" className="item" />
                  <label>Name</label>
                  <input type="text" name="item" className="item" />
                  <label>age</label>
                  <input type="number" name="xyz" className="item" />
                  <label>email</label>
                  <input type="text" name="email" className="item" />
                  <button className="btn-add-item">Add</button>
                </form>
              </div>
            </DialogContentText>
          </DialogContent>
          <DialogActions>
            <Button onClick={this.handleClose.bind(this)} color="primary">
              Cancel
            </Button>
          </DialogActions>
        </Dialog>
      </div>
    );
  }
}

export default FormDialog;

正如您所看到的,提交时的表单调用了 onSubmitForm(),它依次将 4 个输入字段的值传递给父组件。当我使用 alert(p1)、alert(p2) 检查时,这些值正在到达父组件,警报(p3)和警报(p4)。但是我无法使用 this.setState({students: [...this.state.students, {id:{p1},name:{p2},age:{ p3},电子邮件:{p4}}] })。

关于如何设置学生数组的状态并在页面中重新渲染整个数组的任何帮助。

标签: reactjsreact-component

解决方案


这里有多个问题:

这是第一个。

{
  id: { p1: 123 },
  name: { p2: 'test name' },
  age: { p3: 18 },
  email: { p4: 'abc@xyz.com }
}

但是你需要生成像

{
  id: 123,
  name: 'test name',
  age: 18,
  email: 'abc@xyz.com
}

因此,请在您的功能中进行此更改。

onSubmitHandle(p1,p2,p3,p4) { 
  this.setState({students: [...this.state.students, {
    id:p1,
    name:p2,
    age:p3,
    email:p4
  }]})
};

最好将您的参数命名为与密钥相同的名称。

onSubmitHandle(id,name,age,email) { 
  this.setState({students: [...this.state.students, {
    id,
    name,
    age,
    email
  }]})
}; 

在传递给对话框时绑定您的处理程序。

<FormDialog details={this.onSubmitHandle.bind(this)} />

您需要在表单提交操作中使用 event.preventDefault 。

onSubmitForm(event) {
    event.preventDefault();
    this.props.details(
      event.target.id.value,
      event.target.item.value,
      event.target.xyz.value,
      event.target.email.value
    );
  }

我创建了沙盒并修复了您的问题:

编辑 fragrant-sun-ehflg


推荐阅读