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

时间:2018-10-15 10:38:38

标签: javascript reactjs react-native

我错过了什么吗?我正在使用es6样式在this.state中添加到一个空数组,但没有任何东西被推入状态。

我应该在数组中放入两个,但是在console.logging之后什么也没显示。由于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: }

4 个答案:

答案 0 :(得分:2)

.setState()the docs上的一些小笔记:

  

React可以将多个setState()调用批处理为一个更新,以提高性能。

     

由于this.propsthis.state可能是异步更新的,因此不应依赖于它们的值来计算下一个状态。

我只需要在循环开始时使用另一个对象(从当前状态复制),在循环中修改该变量,然后在完成所有循环后在最后执行一个.setState()

答案 1 :(得分:1)

尝试使用setState回调记录输出,如下所示:

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

答案 2 :(得分:0)

setState 异步 。这意味着状态值的值不会立即更新。

您正在做的是遍历一系列值,并将specificList的状态设置为specificList的当前值与数组中单个项的串联。

因此,如果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] })

您可以看到数组中除最后一个值以外的所有值如何被忽略。

解决此问题的一种方法是将函数而不是值传递给setState。这将允许您处理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]
                }));
            }
        });
      });
};

答案 3 :(得分:0)

最好在两个循环中都调用setState。例如。您可以执行以下操作:

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 }); 
}