更新的数组需要使用 react hooks 设置,但会创建无限循环

问题描述

在下面的代码中,我从 Firebase Firestore 获取图像。 url 正确返回并推送到 images state

现在的问题是添加了相同的网址(因为 useEffect 很快或很早就运行了?)

因此,在第二个 useEffect 中,我更新了图像数组并使用 ...new Set 轻松轻松地删除了重复项,但问题是 setimages() 也在那里被调用,这是不允许的,因为这创建无限循环。

所以我的问题是,有人能告诉我在哪里以正确的方式将 updated array uniq 设置为 images state 吗?

提前致谢!

const [evtsFiltered,setEvtsFiltered] = useState([])
const [images,setimages] = useState([])

 useEffect(() => {
    evtsFiltered?.map((item) => {
      storageRef
        .child(item)
        .getDownloadURL()
        .then((url) => {
          setimages((images) => [...images,url]) // url returns a plain string such as 'http://image-1.png'
        })
    })
  },[evtsFiltered])

  useEffect(() => {
    let uniq = [...new Set(images)] // Duplicates are removed
    setimages(uniq) // Infinite loop problem
  },[images])

解决方法

您的代码需要改进:

  • 您不需要将 Windows.Resourcesoptional-chaining 一起使用,因为它的初始值是一个空数组。

  • evtsFiltered 如果您只是要遍历数组,则不适合使用该方法。您可以将 map() 方法与 map() 一起使用来获取图片网址。

  • 由于 Promise.all() 钩子,无法使用相同的 URL。您的 Firebase 存储中有重复的网址,或者您没有正确更新状态。

  • 如果您在第一个 useEffect 挂钩中正确更新 useEffect 状态,则不需要第二个 images 挂钩。

尝试使用 useEffectPromise.all() 方法更新状态,如下所示:

map()

使用 useEffect(() => { const arr = evtsFiltered.map((item) => { return storageRef.child(item).getDownloadURL(); }); Promise.all(arr) .then(urls => { setImages(urls); }) .catch(err => /* handle error */ ); },[evtsFiltered]); 方法,创建一个 Promise 数组,然后您可以使用 map() 方法解析这些承诺。另外,删除第二个 Promise.all() 钩子。

,

这是因为您尝试更新您收听的状态更新。一种解决方案是创建另一个包含独特图像的状态。

build.bat

另一个在第一个效果中设置独特的图像。

const [evtsFiltered,setEvtsFiltered] = useState([])
const [images,setImages] = useState([])
const [uniqueImages,setUniqueImages] = useState([])

 useEffect(() => {
    evtsFiltered?.map((item) => {
      storageRef
        .child(item)
        .getDownloadURL()
        .then((url) => {
          setImages((images) => [...images,url]) // url returns a plain string such as 'http://image-1.png'
        })
    })
  },[evtsFiltered])

  useEffect(() => {
    let uniq = [...new Set(images)] // Duplicates are removed
    setUniqueImages(uniq) // Infinite loop problem
  },[images])