为什么我的setState函数会覆盖当前状态?

时间:2019-09-13 14:18:09

标签: javascript reactjs state setstate

我对React还是比较陌生,我正在尝试使用从读取响应中接收到的数据来设置状态。为此,我链接了一个函数,该函数收集所需的数据,将其添加到状态对象,并使用setState将其添加到State,然后对传入的下一个响应执行相同的操作。

我的问题是每次尝试都将被下一次尝试覆盖,这意味着仅处理最后一个响应并将其添加到状态。

这是我在做什么或做错了吗?

我已经尝试过使用prevState,但是这会破坏页面并产生错误:“无效的尝试传播不可迭代的实例”

 buildDataObject = (str, arr) => {
    this.setState(prevState => [...prevState, {
      name: str,
      labels: arr.map(obj => obj.description),
      id: arr[0].mid
    }]);
  }

这是脚本运行之前的状态:

  constructor(){
    super();
    this.state = {
      images: []
    }
  }

在componentDidMount上,我为数组中的每个图像运行获取请求:

  componentDidMount() {
    images.forEach(index => this.getLabels(index));
  }

这是提取请求:

  getLabels = (path) => {
    const url = getGoogleVisionUrl();
    fetch((url), {
      method: 'POST',
      body: JSON.stringify(createRequestJSON([path]))
    }).then(response => response.json())
      .catch((err) => { console.log('error!', err); })
      .then(data => data.responses[0].labelAnnotations)
      .then(arr => this.buildDataObject(path, arr));
  }

哪个调用应该处理每个响应并将其添加到状态的函数:

  buildDataObject = (str, res) => {
    this.setState([{
      name: str,
      labels: res.map(obj => obj.description),
      id: res[0].mid
    }]);
  }

状态最终成为单个对象,如下:

{
  name: / string response data /,
  labels: /an array or strings/,
  id: /an ID number/
}

1 个答案:

答案 0 :(得分:1)

如果您未指定要在状态下更新的键,则会向其中添加一个对象,并每次都覆盖它,您需要将该对象添加到状态为images的数组中:

buildDataObject = (str, arr) => {
  this.setState(prevState => ({
    images: [
      ...prevState.images,
      {
        name: str,
        labels: arr.map(obj => obj.description),
        id: arr[0].mid
      }
    ]
  }));
};