setState不更新值

时间:2018-12-15 12:32:56

标签: node.js reactjs setstate

对于基于onClick()的图像选择器,我有一个react-photo-galleryonClick()基于selectPhoto(event, obj)示例代码中的react-photo-gallery函数,位于{ {3}}。

我修改后的代码版本已包括一个用于所选图像数量的计数器(例如,我可以为用户 if selected> 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。

2 个答案:

答案 0 :(得分:1)

以这种方式进行工作。 setState调用是异步的。当下一个渲染触发时,所有先前的setState将完成。 您可以向setState添加回调。 setState发生时将调用它。如果您将日志放在此处,它将显示正确的值。

if 11 >= df['age'] <= 20:
    df['age_enc'] = 20
elif 21 >= df['age'] <= 25:
    df['age_enc'] = 25
elif 26 >= df['age'] <= 30:
    df['age_enc'] = 30
elif 31 >= df['age'] <= 35:
    df['age_enc'] = 35       
elif 36 >= df['age'] <= 40:
    df['age_enc'] = 40    
elif 41 >= df['age'] <= 50:
    df['age_enc'] = 50  
elif 51 >= df['age'] <= 60:
    df['age_enc'] = 60  
else:
    df['age_enc'] = 100;

答案 1 :(得分:1)

this.state不应与setState一起使用。由于状态更新是异步的,因此可能会导致争用情况。

状态updater function应该可以解决此问题:

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