在for循环的每次迭代中更新状态

时间:2019-10-31 16:02:57

标签: javascript reactjs firebase firebase-realtime-database firebase-storage

伙计们! 我在遍历for-loop的每次迭代时遇到问题,我的状态中的数组变量仍然保留1个元素。这是我的意见
    <input accept="image/*" type="file" onChange={handlePhotoChange} multiple/> 这就是handlePhotoChange方法

const [images, setImages] = useState([])
const handlePhotoChange = async (event) => {
    const { files } = event.target;

    for (let i = 0; i < files.length; i += 1) {
      const file = files[i];

      if (!file.type.match('image')) {
        continue;
      }

      setImages([...images, { loading: true, src: null }]);
      await firebase.doUploadImage(file, auth.uid);
      const url = await firebase.getImageUrl(file.name, auth.uid);
      setImages([...images.slice(0, -1), { loading: false, src: url }]);
    }
}

我在这里所做的是在将映像上传到Firebase存储中之前将loading变量设置为true,通过此loading我展示了一个加载器。然后我的上传准备好了,我得到了图像的firebase URL,并覆盖了图像数组[]中的最后一个元素。然后,我们继续下一张图片。这样,我将在每个图像上显示一个加载器。但是问题是循环后的images数组只有最后添加的元素。我猜这与setImages函数无关,但正在等待您的意见。谢谢:)

2 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,那么可以解决以下问题的解决方案:

const [images, setImages] = useState([]);

const handlePhotoChange = async (event) => {
    const { files } = event.target;

    setImages([...images, { loading: true, src: null }]);

    let newImagesArray = [];

    for (let i = 0; i < files.length; i += 1) {
      const file = files[i];

      if (!file.type.match('image')) {
        continue;
      }

      await firebase.doUploadImage(file, auth.uid);
      const url = await firebase.getImageUrl(file.name, auth.uid);
      let obj = {loading: false, src: url};
      newImagesArray.push(obj);
    }

    //get state
    let newImages = images;
    //add new images
    newImages.push(newImagesArray)
    //update state
    setImages(newImages);
}

我们正在做的是创建一个临时数组newImages来容纳所有新文件。然后,当我们遍历所有上传的文件后,便将数组置于状态。

让我知道它是否有效/是否有问题。

答案 1 :(得分:0)

是异步的,只需更改一次状态即可。另外,如果要访问以前的状态,则应使用useState的回调版本

const [stateObject, setObjectState] = useState({
  firstKey: '',
  secondKey: '',
});

setObjectState((prevState) => ({
  ...prevState,
  secondKey: 'value',
}));

您可以将加载状态和上传状态分开,以使其易于管理,下面是伪代码

const handlePhotoChange = (event) => {
  const { files } = event.target;
  const loadingImages = [];
  for (let i = 0; i < files.length; i += 1) {
    const file = files[i];

    if (!file.type.match('image')) {
      continue;
    }
    loadingImages.push({ file });

    firebase.doUploadImage(file, auth.uid)
      .then(// add to uploaded images state)
  }
  // set loading images state after iteration is complete
}