首页 > 解决方案 > setState 不更新值

问题描述

我有onClick()一个react-photo-gallery基于图像的选择器(onClick()它基于https://codesandbox.io/s/o7o241q09?from-embed的示例代码中selectPhoto(event, obj)显示的函数)。react-photo-gallery

我修改后的代码版本已经修改为包含一个用于选择图像数量的计数器(例如,如果选择>0,我可以动态地向用户提供下载功能)

我的代码如下所示:

  selectPhoto(event, obj) {
    let photos = this.state.apiItems;
    photos[obj.index].selected = !photos[obj.index].selected;
    this.setState({ apiItems: photos });
    let localSelectedCount=0;
    this.state.apiItems.forEach(function(pVal,pIndex) {
            if (pVal.selected) {
                localSelectedCount = localSelectedCount + 1;
            }
    });
    this.setState({selectedImagesCount:localSelectedCount});
    console.log(localSelectedCount);
    console.log(this.state.selectedImagesCount);
    //
  }

在我班级的顶部,我定义了初始状态:

constructor() {
    super();
    this.state = {
        selectedImagesCount:0,
        apiItems: []
    };
    this.selectPhoto = this.selectPhoto.bind(this);
}

我遇到的问题是localSelectedCount完美地递增和递减。然而this.state.selectedImagesCount总是落后一个。

因此,例如,如果我选择一张图像然后取消选择一张图像,console.log()将输出:

1
0
0
1

当预期的输出当然是:

1
1
0
0

我正在使用 Node v10.14.1 和 React 16.6.3。

标签: node.jsreactjssetstate

解决方案


this.state不应与setState. 由于状态更新是异步的,这可能会导致竞争条件。

状态更新器功能应该解决这个问题:

...
this.setState({ apiItems: photos });
this.setState(state => {
  let localSelectedCount=0;
  // is a good use case for array reduce
  state.apiItems.forEach(function(pVal,pIndex) {
        if (pVal.selected) {
            localSelectedCount = localSelectedCount + 1;
        }
  })
  return {selectedImagesCount:localSelectedCount};
});

异步更新的另一个问题是console.log. setState更新值,但不在console.log调用时更新。这就是回调参数的用途。它应该是:

...
this.setState({ apiItems: photos });
this.setState(state => {
  let localSelectedCount=0;
  // is a good use case for array reduce
  state.apiItems.forEach(function(pVal,pIndex) {
        if (pVal.selected) {
            localSelectedCount = localSelectedCount + 1;
        }
  })
  return {selectedImagesCount:localSelectedCount};
}, () => {
  console.log(this.state.selectedImagesCount);
});

推荐阅读