【问题标题】:React 16 Modal form update operationReact 16 模态表单更新操作
【发布时间】:2017-12-12 12:32:19
【问题描述】:

我是 react-16 的新手,已经完成了 React-16 的保存和删除操作。当涉及到编辑/更新操作时,我发现方法有困难。1)当我点击更新按钮时,打开模式但值没有显示在每个字段中。2)我如何在保存到它们后更新 setState 函数中的表单值。谢谢。

import React, { Component } from "react";
import {Form,FormGroup,FormControl,Col,Button,Modal,ButtonToolbar,Table} from "react-bootstrap";
class Dashboard extends Component {
  constructor(props) {
    super(props);

    this.state = {
      name: "",
      description: "",
      amount: "",
      date: "",
      show: false,
      formdata: []
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.showModal = this.showModal.bind(this);
    this.hideModal = this.hideModal.bind(this);
    this.showEditModal = this.showEditModal.bind(this);
  }

  showModal() {
    this.setState({ show: true });
  }

  showEditModal(event) {
    this.setState({
      show: true,

      name: this.state.name.value,
      description: this.state.description.value,
      amount: this.state.amount.value,
      date: this.state.date.value
    });
  }

  hideModal() {
    this.setState({
      show: false,
      name: "",
      description: "",
      amount: "",
      date: ""
    });
  }

  handleInputChange(event) {
    this.setState({
      [event.target.name]: event.target.value,
      [event.target.description]: event.target.value,
      [event.target.amount]: event.target.value,
      [event.target.date]: event.target.value
    });
  }
  handleSubmit(event) {
    const formItem = {
      name: this.state.name,
      description: this.state.description,
      amount: this.state.amount,
      date: this.state.date
    };

    if (
      this.state.name === "" ||
      this.state.amount === "" ||
      this.state.date === ""
    ) {
      alert("Please fill mandatory filed");
    } else {
      this.setState(prevState => ({
        formdata: prevState.formdata.concat(formItem)
      }));

      alert("form submited: ");

      this.setState({
        name: "",
        description: "",
        amount: "",
        date: ""
      });
    }
    event.preventDefault();
  }

  deleteExpense(i) {
    alert("are you sure you want to Delete this item ?");
    this.setState({
      formdata: this.state.formdata.filter((item, index) => {
        return index !== i;
      })
    });
  }

  render() {
    return (
      <div>
        <p>Welcome</p>

        <ButtonToolbar>
          <Button bsStyle="primary" onClick={this.showModal}>
            Add Expenses
          </Button>
          <Table striped bordered condensed hover>
            <thead>
              <tr>
                <th>name</th>
                <th>description</th>
                <th>amount</th>
                <th>date</th>
                <th>Action</th>
              </tr>
            </thead>
            <tbody>
              {this.state.formdata.map((item, i) => (
                <tr key={i}>
                  <td>{item.name}</td>
                  <td>{item.description}</td>
                  <td>{item.amount}</td>
                  <td>{item.date}</td>
                  <td>
                    <Button bsStyle="warning" onClick={this.showEditModal}>
                      Update
                    </Button>
                    <Button
                      bsStyle="danger"
                      onClick={() => this.deleteExpense(i)}
                    >
                      Delete
                    </Button>
                  </td>
                  <td />
                </tr>
              ))}
            </tbody>
          </Table>
          <Modal
            {...this.props}
            show={this.state.show}
            onHide={this.hideModal}
            dialogClassName="custom-modal"
          >
            <Modal.Header closeButton>
              <Modal.Title
                id="contained-modal-title-lg "
                className="text-center"
              >
                Add Expenses
              </Modal.Title>
            </Modal.Header>
            <Modal.Body>
              <Form horizontal onSubmit={this.handleSubmit}>
                <FormGroup controlId="formHorizontalEmail">
                  <Col smOffset={4} sm={4}>
                    <FormControl
                      type="Text"
                      placeholder="name"
                      name="name"
                      value={this.state.name}
                      onChange={this.handleInputChange}
                    />
                  </Col>
                </FormGroup>
                <FormGroup controlId="formHorizontalPassword">
                  <Col smOffset={4} sm={4}>
                    <FormControl
                      type="description"
                      placeholder="description"
                      name="description"
                      value={this.state.description}
                      onChange={this.handleInputChange}
                    />
                  </Col>
                </FormGroup>
                <FormGroup controlId="formHorizontalPassword">
                  <Col smOffset={4} sm={4}>
                    <FormControl
                      type="amount"
                      placeholder="amount"
                      name="amount"
                      value={this.state.amount}
                      onChange={this.handleInputChange}
                    />
                  </Col>
                </FormGroup>
                <FormGroup controlId="formHorizontalPassword">
                  <Col smOffset={4} sm={4}>
                    <FormControl
                      type="date"
                      placeholder="date"
                      name="date"
                      value={this.state.date}
                      onChange={this.handleInputChange}
                    />
                  </Col>
                </FormGroup>

                <FormGroup>
                  <Col smOffset={5} sm={4}>
                    <Button type="submit" bsStyle="primary">
                      Add
                    </Button>
                  </Col>
                </FormGroup>
              </Form>
            </Modal.Body>
          </Modal>
        </ButtonToolbar>
      </div>
    );
  }
}
export default Dashboard;

【问题讨论】:

    标签: javascript reactjs ecmascript-6


    【解决方案1】:

    在您的openEditModal() 方法中,您需要将状态值设置为您要编辑的记录(您在表中单击的记录)的值。在这种情况下,您将需要查找所选项目,更新状态,然后打开模式。像这样:

    import React, { Component } from "react";
    import {Form,FormGroup,FormControl,Col,Button,Modal,ButtonToolbar,Table} from "react-bootstrap";
    
    class Dashboard extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          name: "",
          description: "",
          amount: "",
          date: "",
          show: false,
          formdata: []
        };
    
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleInputChange = this.handleInputChange.bind(this);
        this.showModal = this.showModal.bind(this);
        this.hideModal = this.hideModal.bind(this);
        this.showEditModal = this.showEditModal.bind(this);
      }
    
      showModal() {
        this.setState({ show: true });
      }
    
      showEditModal(event, i) {
        const recordToEdit = this.state.formdata.filter((item, index) => {
          return index === i;
        })[0];
    
        this.setState({
          show: true,
    
          name: recordToEdit.name,
          description: recordToEdit.description,
          amount: recordToEdit.amount,
          date: recordToEdit.date
        });
      }
    
      hideModal() {
        this.setState({
          show: false,
          name: "",
          description: "",
          amount: "",
          date: ""
        });
      }
    
      handleInputChange(event) {
        // update the input that changed
        this.setState({
          [event.target.name]: event.target.value
        });
      }
      
      handleSubmit(event) {
        const formItem = {
          name: this.state.name,
          description: this.state.description,
          amount: this.state.amount,
          date: this.state.date
        };
    
        if (
          this.state.name === "" ||
          this.state.amount === "" ||
          this.state.date === ""
        ) {
          alert("Please fill mandatory filed");
        } else {
          if (this.state.formdata.filter(item => item.name === formItem.name).length > 0) {
            // update item
            this.setState(prevState => ({
              formdata: prevState.formdata.map(item => {
                if (item.name === formItem.name)
                  return formItem;
                else
                  return item;
              })
            }));
    
          } else {
            // add new item
            this.setState(prevState => ({
              formdata: prevState.formdata.concat(formItem)
            }));
    
          }
    
          alert("form submited: ");
    
          this.setState({
            name: "",
            description: "",
            amount: "",
            date: ""
          });
        }
        event.preventDefault();
      }
    
      deleteExpense(i) {
        alert("are you sure you want to Delete this item ?");
        this.setState({
          formdata: this.state.formdata.filter((item, index) => {
            return index !== i;
          })
        });
      }
    
      render() {
        return (
          <div>
            <p>Welcome</p>
    
            <ButtonToolbar>
              <Button bsStyle="primary" onClick={this.showModal}>
                Add Expenses
              </Button>
              <Table striped bordered condensed hover>
                <thead>
                  <tr>
                    <th>name</th>
                    <th>description</th>
                    <th>amount</th>
                    <th>date</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                  {this.state.formdata.map((item, i) => (
                    <tr key={i}>
                      <td>{item.name}</td>
                      <td>{item.description}</td>
                      <td>{item.amount}</td>
                      <td>{item.date}</td>
                      <td>
                        <Button bsStyle="warning" onClick={(e) => this.showEditModal(e, i)}>
                          Update
                        </Button>
                        <Button
                          bsStyle="danger"
                          onClick={() => this.deleteExpense(i)}
                        >
                          Delete
                        </Button>
                      </td>
                      <td />
                    </tr>
                  ))}
                </tbody>
              </Table>
              <Modal
                {...this.props}
                show={this.state.show}
                onHide={this.hideModal}
                dialogClassName="custom-modal"
              >
                <Modal.Header closeButton>
                  <Modal.Title
                    id="contained-modal-title-lg "
                    className="text-center"
                  >
                    Add Expenses
                  </Modal.Title>
                </Modal.Header>
                <Modal.Body>
                  <Form horizontal onSubmit={this.handleSubmit}>
                    <FormGroup controlId="formHorizontalEmail">
                      <Col smOffset={4} sm={4}>
                        <FormControl
                          type="Text"
                          placeholder="name"
                          name="name"
                          value={this.state.name}
                          onChange={this.handleInputChange}
                        />
                      </Col>
                    </FormGroup>
                    <FormGroup controlId="formHorizontalPassword">
                      <Col smOffset={4} sm={4}>
                        <FormControl
                          type="description"
                          placeholder="description"
                          name="description"
                          value={this.state.description}
                          onChange={this.handleInputChange}
                        />
                      </Col>
                    </FormGroup>
                    <FormGroup controlId="formHorizontalPassword">
                      <Col smOffset={4} sm={4}>
                        <FormControl
                          type="amount"
                          placeholder="amount"
                          name="amount"
                          value={this.state.amount}
                          onChange={this.handleInputChange}
                        />
                      </Col>
                    </FormGroup>
                    <FormGroup controlId="formHorizontalPassword">
                      <Col smOffset={4} sm={4}>
                        <FormControl
                          type="date"
                          placeholder="date"
                          name="date"
                          value={this.state.date}
                          onChange={this.handleInputChange}
                        />
                      </Col>
                    </FormGroup>
    
                    <FormGroup>
                      <Col smOffset={5} sm={4}>
                        <Button type="submit" bsStyle="primary">
                          Add
                        </Button>
                      </Col>
                    </FormGroup>
                  </Form>
                </Modal.Body>
              </Modal>
            </ButtonToolbar>
          </div>
        );
      }
    }
    export default Dashboard;

    请注意,我将索引传递给showEditModal() 函数,以便我可以使用所选记录更新状态。另外,我正在使用每个表单输入上的name="field_name" 属性更新handleInputChange() 方法中的字段。

    旁注:根据React docs:

    如果项目的顺序可能发生变化,我们不建议对键使用索引。这会对性能产生负面影响,并可能导致组件状态出现问题。

    考虑为每条记录使用唯一 ID,而不是 map 函数提供的索引。

    【讨论】:

    • 谢谢它解决了第一个问题,但是对于第二个问题,当我用新值更新它时,它会创建新条目而不是更新旧条目。
    • 那是因为您在先前的状态上使用了.concat(),它只是将项目添加到数组的末尾。我已经更新了我的答案,以提供一种更新状态中项目的方法。
    • 我用更新的代码替换了,但是当我添加值并保存时,它根本没有输入任何条目。
    • 我很抱歉。我没有意识到您在同一事件中添加和更新。我已更新我的代码以反映此更改。
    • 我在保存时收到错误消息,因为无法读取未定义过滤器的属性,并且页面刷新速度非常快,并且没有保存任何数据。
    猜你喜欢
    • 2022-08-17
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    相关资源
    最近更新 更多