【问题标题】:React with Hooks: When do re-renders happen?React with Hooks:什么时候重新渲染?
【发布时间】:2019-08-02 01:37:38
【问题描述】:

使用 hooks 的 React 组件何时会重新渲染?

让我们假设组件:

  • 使用useState 管理状态
  • 从其父级接收props

是否会直接在以下事件之后发生重新渲染,并且仅在这些时间点发生?

  • 组件接收新的props
  • state 已更新

相关问题

假设组件有多个useState 表达式,并且用户交互导致多个状态更新。

组件是否会重新渲染多次,每次更改的state 值一次,还是会将这些相关更改批处理到一次重新渲染中?

【问题讨论】:

  • react devtools 很适合回答您的问题,您只需检查突出显示选项,看看您的组件是否多次渲染
  • 状态更新和道具更新会导致组件重新渲染。多个同步状态更新将被批处理到一个重新渲染中
  • @Tholle 我同意,希望能回答你的问题
  • @G.aziz 你能解释一下如何使用 react devtools 找到它吗
  • @BuddhikaW 这是您可以在选项中找到的复选框

标签: javascript reactjs react-hooks


【解决方案1】:

考虑到组件没有为类组件实现 shouldComponentUpdate 或正在使用 React.memo 的功能,组件将在以下情况下重新渲染

  • 组件接收新的道具
  • 状态已更新
  • 上下文值被更新(如果组件使用 useContext 监听上下文变化)
  • 由于上述任何原因导致父组件重新渲染

假设组件有几个 useState 表达式和一个用户 交互导致多个状态更新。

组件是否会重新渲染多次,每个状态值一次 已更改,还是会将这些相关更改批量处理为一个 重新渲染?

useState 不会将更新后的值与之前的值合并,而是像setState 那样执行批处理,因此如果同时完成多个状态更新,则会进行一次渲染。

【讨论】:

  • 谢谢!多个状态一起更新是什么意思?
  • 我的意思是,如果你有两个状态变量 countA 和 countB 并且你使用它们各自的状态设置器一个接一个地更新它们,它们是批处理的
  • 抱歉,您的意思是在 JS 事件循环的一个滴答声内? IE。在什么情况下它们不被批处理?
  • 如果多次调用 useState setter,它们的更新将被批处理,有一个小的时间间隔。但是,如果 setter 调用发生的最小时间间隔大于批处理间隔,那么这些更新将不会被批处理
  • “组件接收新道具”不应出现在此列表中。它本身不会重新渲染。见stackoverflow.com/a/38893045/3032209
【解决方案2】:

在此主题上找到 this nice article。如果有人需要快速阅读,我会添加摘要。

是什么导致了 react 中的渲染?

状态修改

组件在其状态被操作时重新渲染,就这么简单。因此,当您修改组件的状态时,它往往会使用新的状态值重新渲染。

传递道具

如果父组件触发了重新渲染,所有子组件也将重新渲染,通常您只希望特定子组件仅在组件正在使用某些道具或修改了传递的道具时才重新渲染,但这不是在这种情况下,无论 props 是否被消费、修改与否,如果父组件触发了渲染,子组件将重新渲染。

使用上下文 API

当修改状态(也是传递给上下文的值)时,整个子组件树将被重新渲染。同样,子组件是否正在使用上下文数据并不重要,它仍然会重新渲染。重新渲染取决于传递给提供者的值,但仍然会重新渲染整个组件树。

传递参考

如果对象、数组和函数比较基于引用,即确切的内存位置,因此即使它们看起来相等,它们的比较也会产生错误,在 React Object.is 方法中用于比较不同的值。

例子:

{}==={}             //false
[]===[]             //false
{a: 5}==={a: 5}     //false
[1,2,3]===[1,2,3]   //false

(前一个状态和新状态比较时,返回false,因为它们没有相同的引用,只有值相同)

【讨论】:

    猜你喜欢
    • 2020-07-07
    • 2023-02-20
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 2020-06-19
    • 2021-04-21
    相关资源
    最近更新 更多