ReactJS - setState 以一种奇怪的方式工作

ReactJS - setState working in a weird way

我正在尝试以状态数组的形式将内容添加到列表中。但是,使用我当前的代码,第一项无法正确添加。

export default class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [],
      total: 0.00,
      ...
    }
  }

  //some unimportant code here

  addToList = item => {
    this.setState({list: [...this.state.list, item]});

    //This method call for a method that gets the total price of all the items
    this.getTotal(); 
  }

  //this method works fine, except with the first element
  getTotal() {
    this.setState(({sum= 0.0, items, list}) => {
      items.forEach(element => {
        if(this.state.list.length !== 0.0) {
          if(this.state.list.includes(element.name)) {
            sum += parseFloat(element.price);
          }
        }
      });
      this.setState({total: sum});
    });
  }
}

当我 console.log list 状态时,我得到第一个项目的空数组,然后项目延迟一个。因此,如果我添加项目 A 并查看控制台,我什么也看不到。当我添加项目 B 并查看控制台时,我看到带有项目 AArray。关于造成这种情况的原因有什么想法吗?

请记住 setState 是异步的,因此如果您想检查更新的列表,您必须向 setState 添加回调:

 addToList = item => {
    this.setState( {list: [...this.state.list, item]}, () =>{ 
     // So if you make anything here, you are sure that the state was updated successfully 
    console.log( this.state.list );
    this.getTotal();
    } );
  }

每次访问 this.state.list 都应替换为 listthis.state.list 访问潜在的旧状态。传递回调的全部意义在于您可以访问作为参数传递的当前状态。您对 items 正确执行此操作,但对 list.

不正确

您还应该从 setState 回调中 return {total: sum} 而不是调用 this.setState:

  getTotal() {
    this.setState(({items, list}) => {
      const sum = 0;
      items.forEach(element => {
        if(list.includes(element.name)) {
          sum += parseFloat(element.price);
        }
      });
      return {total: sum};
    });
  }

出于同样的原因,您应该在 addToList 中使用回调函数:

 addToList = item => {
   this.setState(({list}) => ({list: [...list, item]}));
   this.getTotal(); 
 }