【问题标题】:Tmp array not properly added to state variable - React - HooksTmp 数组未正确添加到状态变量 - React - Hooks
【发布时间】:2021-03-15 08:48:07
【问题描述】:

我创建并将 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",
]

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

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

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

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

这怎么可能?

提前致谢

【问题讨论】:

    标签: arrays reactjs foreach react-hooks react-state


    【解决方案1】:

    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]);
    

    【讨论】:

    • Khatri 感谢您的回复,但使用这种方法仍然只有 2 个 url 被添加到 state ...
    • 我尝试了答案,但这给我返回了以下错误:cannot read property 'flat' of undefined
    • 我还更新了我的问题,以便您可以准确地看到 console.log() 的结果是什么
    • 好吧,数据是未定义的,返回的承诺将是未定义的。你可以像promises?.flat() 一样使用它
    • 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
    猜你喜欢
    • 2018-12-31
    • 2019-08-08
    • 1970-01-01
    • 2018-05-27
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    相关资源
    最近更新 更多