当前位置: 首页 > 知识库问答 >
问题:

javascript - React中为什么 dependency 每次渲染时值相同的情况下 useMemo的参数函数会执行多次?

巫化
2024-09-12

demo

image.png

问题:

这个demo的代码 来自于 https://zh-hans.react.dev/reference/react/useTransition 的示例代码,fork后修改了PostsTab组件的逻辑.
问题: 为什么 requestUrl每次渲染时值相同的情况下 useMemo的参数函数会执行多次?
image.png

共有2个答案

云英才
2024-09-12

因该没有重复执行 只是因为你的APP 被 StrictMode严格模式包裹了,去掉就行。

太叔永新
2024-09-12

在React中,useMemo函数的行为可能会受到多种因素的影响,尽管其设计初衷是为了避免在每次渲染时都重新计算某些值,但如果依赖项(dependency)列表中的值在引用上发生变化,或者React的渲染逻辑导致组件被重新渲染,那么useMemo中的函数仍然可能会被多次调用。

针对你提到的问题,有几个可能的原因导致useMemo的参数函数执行多次:

  1. 依赖项(dependency)的变化

    • 如果useMemo的依赖项列表中包含了会变化的引用(如对象、数组等),即使这些对象的内容保持不变,但由于它们是新的引用,React会认为依赖项已经变化,从而重新执行useMemo中的函数。
    • 在你的示例中,如果requestUrl是从props或其他状态变量中派生的,并且这些源变量在每次渲染时都是新的引用(例如,通过每次渲染都创建的新对象或数组),那么即使requestUrl的值看起来相同,useMemo也会因为依赖项的变化而重新计算。
  2. 父组件的重新渲染

    • 如果PostsTab组件的父组件因为某些原因(如props变化、state更新、key变化等)被重新渲染,那么PostsTab组件也会被重新渲染。在React中,组件的重新渲染会重新执行其内部的hooks,包括useMemo
  3. React的渲染优化和并发模式

    • 在React的并发模式(Concurrent Mode)下,React可能会更频繁地执行组件的渲染过程,以评估哪些内容需要被实际渲染到屏幕上。这可能会导致即使在某些情况下依赖项没有变化,useMemo中的函数也被多次调用。然而,请注意,这种情况在普通的同步模式下不太常见。

为了解决这个问题,你可以:

  • 确保useMemo的依赖项是稳定的引用,或者只包含基本数据类型(如数字、字符串等),这样可以避免因为引用变化而导致的重新计算。
  • 使用React.memo来包装组件,这样可以在组件的props没有实际变化时避免不必要的渲染。
  • 仔细检查父组件,确保它们不会因为不必要的props变化或state更新而导致子组件的重新渲染。

如果requestUrl是直接从props或state中获取的,并且你确信它在渲染之间是稳定的(即内容相同且引用也相同),那么你可以考虑将requestUrl作为useMemo的依赖项,并检查其他可能导致组件重新渲染的因素。如果requestUrl是通过复杂逻辑或计算得出的,那么你可能需要确保这个逻辑或计算本身是稳定的,并且不会在每次渲染时都产生新的引用。

 类似资料: