将 UseMemo 与 UseEffect 结合使用时避免无限循环

2024-02-08 22:48:52 浏览数 (1)

useEffect(setup, dependency?) useEffect(设置,依赖项?)setup是一个函数,每次dependencies更改数组中的某些值时都会运行。

const cachedValue = useMemo(calculateValue, dependency) const cachedValue = useMemo(calculateValue, 依赖项)calculateValue是一个函数,每次dependencies更改数组中的某些值时都会运行,然后缓存新值。

我们来看看什么时候会出现无限循环。 这是一个例子:

代码语言:javascript复制
import { useEffect, useMemo, useState } from "react"

export const InfiniteCountUp = () => {
  const [count, setCount] = useState(0)

  const cachedMemo = useMemo(() => count * 2, [count])

  useEffect(() => {
    console.log("Triggered")
  }, [cachedMemo])

  return (
    <div>
      <p>{cachedMemo}</p>
      <button onClick={() => setCount(count   1)}>Increment</button>
    </div>
  )
}

每次点击 Increment 按钮时,都会更新,由于useMemo 依赖数组中的依赖,count会触发值的重新计算。随后,useEffect 被触发,因为它取决于更新的值。 这一系列事件可能会导致无限循环。cachedMemocountcachedMemo

另一个例子是获取数据时。

代码语言:javascript复制
import { useEffect, useMemo, useState } from "react"

export const InfiniteDataFetching = ({ postId }) => {
  const [post, setPost] = useState("")

  const cachedMemo = useMemo(() => {
    const { postId } = post
    return postId
  }, [post])

  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(`https://example.blog/${postId}`)
        const data = await res.json()
        setPost(data)
      } catch (error) {
        console.error(error)
      }
    }

    fetchData()
  }, [postId, cachedMemo])

  return <div>{post && <p>{post.article}</p>}</div>
}

在此示例中,每次postId更改时,都会获取新数据,设置新帖子。此设置会创建潜在的无限循环:postId触发 useEffect 的更改,并且在每次渲染期间重新计算记忆cachedMemo值,可能导致重复调用效果。

为了避免无限循环,最好仔细考虑整体流程。随着代码变大,很容易修复较小的部分,而无需了解整个情况。因此,退后一步并理解代码不同部分之间的交互可以帮助我们避免无限循环并决定真正需要包含哪些依赖项

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

0 人点赞