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

问题描述 投票:2回答:2

家伙!在遍历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函数无关,但正在等待您的意见。谢谢:)

javascript reactjs firebase firebase-realtime-database firebase-storage
2个回答
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
}

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来容纳所有新文件。然后,当我们遍历所有上传的文件时,便将数组置于状态。

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

© www.soinside.com 2019 - 2024. All rights reserved.