简体   繁体   English

为什么我的this.setState不更新数组

[英]why is my this.setState not updating the array

am I missing something? 我错过了什么吗? I'm using es6 style to add to an empty array in this.state, but nothing is getting pushed to state. 我正在使用es6样式在this.state中添加到一个空数组,但是没有任何东西被推入状态。

I should be getting two inside of the array, but after console.logging nothing is showing. 我应该在数组中放入两个,但是在console.logging之后什么也没显示。 and my screen is not rerendering, since coponentDidUpdate is not running. 由于coponentDidUpdate没有运行,所以我的屏幕没有重新渲染。

 class HomeModal extends Component { constructor(props) { super(props); this.state = { specificList: [] }; this.updateState = this.updateState.bind(this); } componentWillMount() { this.updateState(); } componentDidUpdate() { console.log("after update: ", this.state.specificList); } updateState = () => { this.props.completeList.forEach(index => { index.list.forEach(innerArr => { if (innerArr.muscleGroup === this.props.selectedBodyPart) { console.log("test: ", innerArr); this.setState({ specificList: [...this.state.specificList, innerArr.title] }); } }); console.log("after each loop: ", this.state.specificList); }); }; 

 // console.log results 06:22:48: test: Object { 06:22:48: "muscleGroup": "Chest", 06:22:48: "title": "Barbell Bench Press", 06:22:48: } 06:22:48: after each loop: Array [] 06:22:48: test: Object { 06:22:48: "muscleGroup": "Chest", 06:22:48: "title": "Barbell Bench Press", 06:22:48: } 06:22:48: after each loop: Array [] 06:22:48: after each loop: Array [] 6:08:04: Object { // what innerArr the object looks like 06:08:04: "muscleGroup": "Chest", 06:08:04: "title": "Barbell Bench Press", 06:08:04: } 

Some small notes on .setState() from the docs : 文档中有关.setState()一些小注释:

React may batch multiple setState() calls into a single update for performance. React可以将多个setState()调用批处理到单个更新中以提高性能。

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. 由于this.propsthis.state可以异步更新,因此您不应依赖于它们的值来计算下一个状态。

I would simply use another object at the start of the loop (Copying from the current state), modify that variable in the loop, and then do one .setState() at the very end, after all your loops are done. 我将简单地在循环开始时使用另一个对象(从当前状态复制),在循环中修改该变量,然后在完成所有循环后在最后执行一个.setState()

Try to log the output with setState callback, like this: 尝试使用setState回调记录输出,如下所示:

this.setState({
    specificList: [...this.state.specificList, innerArr.title]
}, () => {
    console.log("after each loop: ", this.state.specificList);
});

setState is asynchronous . setState异步的 That means that the value of the state values don't update immediately. 这意味着状态值的值不会立即更新。

What you are doing is looping through a series of values and setting the state of specificList to the concatenation of the current value of specificList plus a single item from the array. 你在做什么是通过一系列的价值观和循环的状态设置specificList到的当前值的串联specificList加上从阵列中的单个项目。

So if specificList were ['a', 'b', 'c'] and the array you're looping over were [1, 2, 3] , then you would essentially be calling: 因此,如果specificList['a', 'b', 'c'] ,而要遍历的数组为[1, 2, 3] ,那么您实际上将在调用:

setState({ specificList: ['a', 'b', 'c', 1] })
setState({ specificList: ['a', 'b', 'c', 2] })
setState({ specificList: ['a', 'b', 'c', 3] })

You can see how all of the values of the array except for the last one get left out. 您可以看到除最后一个数组之外的所有其他值。

One way to fix this is to pass a function to setState instead of a value. 解决此问题的一种方法是将函数而不是值传递给setState This will allow you to work with setState 's asynchronous behavior: 这将允许您使用setState的异步行为:

updateState = () => {
    this.props.completeList.forEach(index => {
        index.list.forEach(innerArr => {
            if (innerArr.muscleGroup === this.props.selectedBodyPart) {
                console.log("test: ", innerArr);
                this.setState(({ specificList } => ({
                  specificList: [...specificList, innerArr.title]
                }));
            }
        });
      });
};

It would be best to call setState once you have looped through both of you loops. 遍历两个循环后最好调用setState。 For eg. 例如。 you can do something like this: 您可以执行以下操作:

updateState = () => {
  let temp = this.state.specificList;

  this.props.completeList.forEach(index => {
    index.list.forEach(innerArr => {
      if (innerArr.muscleGroup === this.props.selectedBodyPart) {
        console.log("test: ", innerArr);
        temp.push(innerArr.title);
      }
    });
    console.log("after each loop: ", temp)
  });

  this.setState({ specificList: temp }); 
}

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

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