简体   繁体   English

Antd Modal如何更新里面的值

[英]Antd Modal how to update the value in it

I'm using Antd Modal to display order information by passing props to TableDetail Component.我正在使用 Antd Modal 通过将道具传递给 TableDetail 组件来显示订单信息。 The thing is when I try to remove the items in the order I use setState and the modal won't update its data.问题是当我尝试按照我使用 setState 的顺序删除项目时,模态不会更新其数据。

https://codesandbox.io/s/antd-reproduction-template-forked-vu3ez A simple version of reproduction is provided above. https://codesandbox.io/s/antd-reproduction-template-forked-vu3ez上面提供了一个简单的复制版本。

enter image description here After I click on the remove button the items remain unchanged but when I close and open the modal it will update.在此处输入图像描述单击删除按钮后,项目保持不变,但当我关闭并打开模态时,它会更新。 enter image description here在此处输入图片说明

What should I do to make it change?我该怎么做才能改变它? I tried forceUpdate() but it won't work.我试过 forceUpdate() 但它不起作用。

Here is the TableDetail component.这是 TableDetail 组件。

export default class TableDetail extends Component {
  constructor(props) {
    super(props);
    this.state = {
      tableOrder: props.tableOrder,
      column: []
    };
  }

  tableInitializer = () => {
    const column = [
      {
        title: "name",
        render: (item) => {
          return <span>{item.name}</span>;
        }
      },
      {
        title: "price",
        render: (item) => {
          return item.price;
        }
      },
      {
        title: "amount",
        render: (item) => {
          return <span>{item.amount}</span>;
        }
      },
      {
        title: "removeButton",
        render: (item) => {
          return (
            <Button
              type="link"
              style={{ color: "red" }}
              onClick={() => this.props.removeItem(item)}
            >
              Remove
            </Button>
          );
        }
      }
    ];
    this.setState({
      column
    });
  };

  UNSAFE_componentWillMount() {
    this.tableInitializer();
  }

  render() {
    return (
      <Modal
        visible={true}
        title={
          <span style={{ fontSize: "1.5rem", fontWeight: "bold" }}>
            Table: {this.state.tableName}
          </span>
        }
        cancelText="Cancel"
        okText="OK"
        onCancel={this.props.hideModal}
      >
        <Table
          columns={this.state.column}
          dataSource={this.state.tableOrder}
          rowKey="name"
        />
      </Modal>
    );
  }
}

TableDetail.propTypes = {
  tableOrder: PropTypes.array.isRequired,
  tableName: PropTypes.string.isRequired,
  hideModal: PropTypes.func.isRequired,
  removeItem: PropTypes.func.isRequired
};

The issue in your code is in removeItem .您代码中的问题出在removeItem You are trying to mutate tableOrder.您正在尝试改变 tableOrder。 According to react docs :根据反应文档

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made.永远不要直接改变 this.state,因为之后调用 setState() 可能会替换你所做的改变。 Treat this.state as if it were immutable将 this.state 视为不可变的

setState() does not immediately mutate this.state but creates a pending state transition. setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。 Accessing this.state after calling this method can potentially return the existing value.调用此方法后访问 this.state 可能会返回现有值。

So that is why it is kind of asynchronous and you can't see your updated changes.所以这就是为什么它有点异步并且您看不到更新的更改。 You need to do this:你需要这样做:

removeItem = (item) => {
    const { tableOrder } = this.state;
    const newTable = [...tableOrder]; <- Create new variable and update variable
    for (let i = 0; i < newTable.length; i++) {
      if (item.name === newTable[i].name) {
        console.log("Got it! " + newTable[i].name);
        newTable.splice(i, 1);
        console.log("new table: ", tableOrder);
        break;
      }
    }
    this.setState({
      tableOrder: newTable <- update here
    });
  };

You dont need to actually modify array you can simply do this also:您不需要实际修改数组,您也可以简单地执行此操作:

this.setState(
{
tableOrder: this.state.tableOrder.filter(data => !(data.name===item.name))
}
)
//filter creates new array

Here is demo: https://codesandbox.io/s/antd-reproduction-template-forked-j4bfl?file=/tables.js这是演示: https : //codesandbox.io/s/antd-reproduction-template-forked-j4bfl?file=/tables.js

You can use the filter method in your removeItem function您可以在removeItem函数中使用filter方法

  removeItem = (item) => {
    const filtered = this.state.tableOrder.filter(
      (order) => item.name !== order.name
    );
    console.log(item, filtered);
    this.setState({
      tableOrder: filtered
    });
  };

and one more thing you should avoid assigning your props to state like还有一件事你应该避免将你的道具分配给状态,比如

   this.state = {
      tableOrder: props.tableOrder,
    };

instead of assigning to state directly use that as props like而不是分配给状态直接使用它作为道具

     <Table
      dataSource={this.props.tableOrder}
     />

In most cases, this is an antipattern.在大多数情况下,这是一种反模式。 Don't “copy props into state.”不要“将道具复制到状态”。 It creates a second source of truth for your data, which usually leads to bugs.它为您的数据创建了第二个真实来源,这通常会导致错误。 One source of truth is best.最好的真相来源之一。

Improved code Live demo改进的代码现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM