useEffect无限循环异步

时间:2020-01-24 17:23:47

标签: javascript reactjs asynchronous react-hooks use-effect

  const [allCases, setAllCases] = useState([])
  const [myCases, setMyCases] = useState([])
  const [sharedCases, setSharedCases] = useState([])
  const [favoriteCases, setFavoriteCases] = useState([])


useEffect(()=> {
    getData(_id).then(res => {
      const favoriteIds = res.data.find(i => i._id === _id).cases.map(x => {
        return x._id
      })
      setAllCases(res.cases.map(x => {
        if (favoriteIds.includes(x._id)) {
          return { ...x, isfavorite: true }
        }
        return { ...x, isfavorite: false }
      }))
      allCases && setSharedCases(allCases.filter(x => x.creator._id !== user._id))
      allCases && setMyCases(allCases.filter(x => x.creator._id === user._id))
      allCases && setFavoriteCases(allCases.filter(x => x.isfavorite))
    })

  }, [])

你好,我遇到无限循环问题。如果包含方括号,则不会填充经过筛选的案例。如果我添加另一个useEffect,即使没有更改allCases,我也会陷入无限循环。 (想知道为什么)

如何解决此异步问题?

2 个答案:

答案 0 :(得分:0)

一种绕过此问题的简单方法是使用局部变量而不是状态来调用其他useState setter。然后,您可以使用相同的变量更新allCases状态,而不必解决异步功能。

useEffect(()=> {
  getData(_id).then(res => {
    const favoriteIds = res.data.find(i => i._id === _id).cases.map(x => {
      return x._id
    })

    // Save it to a local variable so that we have the value immediately
    const newAllCases = res.cases.map(x => {
      if (favoriteIds.includes(x._id)) {
        return { ...x, isfavorite: true }
      }
      return { ...x, isfavorite: false }
    })

    // Use the local variable to update state
    setSharedCases(newAllCases.filter(x => x.creator._id !== user._id))
    setMyCases(newAllCases.filter(x => x.creator._id === user._id))
    setFavoriteCases(newAllCases.filter(x => x.isfavorite))

    // Set the state for allCases
    setAllCases(newAllCases)
  })
}, [])

答案 1 :(得分:0)

在设置allCases和其他参数之前,未设置useEffect中的

sharedCases。同样,在[]中使用useEffect时,它将仅在组件加载时调用该函数。因此您的其他状态值将无法设置。

我建议将useEffect与单独的[allCases]并在那里设置所有其他值。像下面这样

useEffect(()=> {
    getData(_id).then(res => {
      const favoriteIds = res.data.find(i => i._id === _id).cases.map(x => {
        return x._id
      })
      setAllCases(res.cases.map(x => {
        if (favoriteIds.includes(x._id)) {
          return { ...x, isfavorite: true }
        }
        return { ...x, isfavorite: false }
      }))
    })
  }, [])

useEffect(() => {
      // do filter and set the state
}, ['allCases'])