Tmp 数组未正确添加到状态变量 - React - Hooks

Tmp array not properly added to state variable - React - Hooks

我创建并推送 url 的 newArray 未正确添加到我的状态变量 (propFiles)

const [propFiles, setPropFiles] = useState([]);
  useEffect(() => {
    let newArray = [...propFiles];
    data?.forEach((element) => {
      element?.images?.forEach((el) => {
        storageRef
          .child(element.firebaseRef + "/" + el)
          .getDownloadURL()
          .then((url) => {
            console.log(url) // this returns url's like "https://firebase/my-picture.jpg"
            newArray.push(url);
            console.log(newArray) // this updates the array as expected so the result of newArray is ok
            setPropFiles(...propFiles, newArray) // This is where something goes wrong
          });
      });
    });
  }, [data]);


useEffect(() => {
    console.log(propFiles); // The complete array values (of newArray) are not transfered proper to state. Only the first 2 url's are
  }, [propFiles]);

所以在每个 console.log 之后你可以找到我关于正在发生的事情的信息。

如您所见,如果我尝试记录 propFiles,它只会显示 foreach 循环的前 2 个元素,而不是完整的 newArray

有人可以向我解释什么是 set state 等于完整的 newArray 的正确方法吗?

更新 更清楚地了解 newArraypropFiles

的结果

这是 newArrayforeach 之后的样子:

[
    0: "https://firebase/my-picture-1.jpg",
    1: "https://firebase/my-picture-2.jpg",
    2: "https://firebase/my-picture-3.jpg",
    3: "https://firebase/my-picture-4.jpg",
    4: "https://firebase/my-picture-5.jpg",
    5: "https://firebase/my-picture-6.jpg",
    6: "https://firebase/my-picture-7.jpg",
    7: "https://firebase/my-picture-8.jpg",
    8: "https://firebase/my-picture-9.jpg",
    9: "https://firebase/my-picture-10.jpg",
    10: "https://firebase/my-picture-11.jpg",
    11: "https://firebase/my-picture-12.jpg",
]

所以里面有 11 个 url(或字符串)的 array

这是 propFiles 设置为等于 newArray 后的样子:

[
    0: "https://firebase/my-picture-1.jpg",
    1: "https://firebase/my-picture-2.jpg"
]

所以一个 array 里面只有 2 urls(或字符串)。

这怎么可能?

提前致谢

propFiles state 是一个数组,因此您正在更新它,您应该设置一个数组,但您设置的是逗号分隔值

正确的更新方式是

setPropFiles(newArray)

因为您在初始化 newArray

时已经使用了 propFiles

然而,另一件需要注意的事情是你正在遍历元素并更新状态,获取最终更新的数组并只更新一次总是更好。这样做的方法是映射项目并使用 Promise.all

const [propFiles, setPropFiles] = useState([]);
  useEffect(() => {
    const promises = data?.map((element) => {
      return element?.images?.map((el) => {
        return storageRef
          .child(element.firebaseRef + "/" + el)
          .getDownloadURL()
          .then((url) => {
            console.log(url) // this returns url's like "https://firebase/my-picture.jpg"

            console.log(newArray) // this updates the array as expected so the result of newArray is ok
            return url
          });
      });
    }).filter(Boolean); // remove all undefined values
  
// flatten the promise array since we have nested maps
const promisesArr = promises?.flat();
promisesArr && Promise.all(promisesArr).then(newArray => {
         setPropFiles(prevPropsFiles => [...prevPropsFiles, ...newArray])
    })
  }, [data]);