React 递归重新渲染子组件,但存在一个微妙之处。

原文链接: alexsidorenko.com/blog/react-...

作者:Alex Sidorenko

本篇文章主要聊聊 React 渲染子组件的时候,是否会产生重复渲染的问题,以及为什么会产生这种问题,还有如何规避的一些思考。

我们首先来看一个现象,如果说,这里直接用 Hello,而不用子组件,那么 Resizer 和 Hello 都会被重新渲染。

但如果你传入了 children,这里就智慧重新渲染 resizer。

等一下... React 在状态更新时会递归重新渲染子组件吗?

是的 - 看看这个。然而,重新渲染并不等于 DOM 更新。React 使用协调算法(reconciliation)仅更新 DOM 中所需的最小部分。

那么,为什么 React 不重新渲染 children 属性呢?

React 递归地重新渲染,当它遇到能够保留与上一次渲染相同引用标识的元素时,就可以停止递归。

传递给组件的 props 在组件状态更新时保留其标识。这就是为什么以这种方式组织组件可以作为记忆化的替代方案。

我们可以先来看看,如果不用子组件,直接用 Hello 组件,会有什么效果。

  1. 在重新渲染的时候,会进行比较,看两次是不是相同的
  1. 然后比较 props 的时候,会发现不同,所以需要重新渲染。

那如果是使用子组件的情况呢?

那么会判断它两个是相等的,然后不进行重新渲染。

**但是为什么传递的 props 在重新渲染之间保留标识呢? **

在上面的例子中,children 属性来自 Resizer 的父组件。当我们触发 Resizer 的状态更新时,Resizer 会重新渲染,但其父组件不会。

因此, 元素不会被重新创建,保持了在 Resizer 重新渲染之间的引用标识。请注意,如果更新父组件的状态,所有内容都将重新渲染。

这种优化不仅适用于 children,而且适用于任何 props,比如下面的这个例子。

js 复制代码
// When the state of "Resizer" updates
//"children" and "handle" won't re-render
function Resizer({ children, handle }) {
  let [x, updateX] = useState(0)
  return (
    <div style={{ width: x }}>
      {children}
      <span>{handle}</span>
    </div>
  )
}

我如何在实践中使用它?

这个功能与状态共置技术紧密相连。 通过以一种方式组织组件,将状态与更新此状态的 UI 部分隔离,它自然而然地实现了对 React 应用的优化 在没有使用 refs 和 memo 的情况下优化 React 性能。

不要将本指南作为过分分析重新渲染的理由,因为这是事倍功半的。

编码挑战:LongList 组件在每次鼠标移动时重新渲染,导致性能问题。

你能否通过应用本文中的技术来改善应用的性能?CodeSandbox链接

将包含解决方案的链接作为回复发送给这条推文。

相关文章:

  1. 《在你使用 memo 之前》(作者:Dan Abramov)
  2. 《优化 React 重新渲染的一个简单技巧》(作者:Kent C. Dodds)
  3. 《React 渲染行为的(基本上是)完整指南》(作者:Mark Erikson)
相关推荐
wearegogog1232 小时前
基于 MATLAB 的卡尔曼滤波器实现,用于消除噪声并估算信号
前端·算法·matlab
Drawing stars2 小时前
JAVA后端 前端 大模型应用 学习路线
java·前端·学习
品克缤2 小时前
Element UI MessageBox 增加第三个按钮(DOM Hack 方案)
前端·javascript·vue.js
小二·2 小时前
Python Web 开发进阶实战:性能压测与调优 —— Locust + Prometheus + Grafana 构建高并发可观测系统
前端·python·prometheus
小沐°2 小时前
vue-设置不同环境的打包和运行
前端·javascript·vue.js
qq_419854053 小时前
CSS动效
前端·javascript·css
烛阴3 小时前
3D字体TextGeometry
前端·webgl·three.js
桜吹雪3 小时前
markstream-vue实战踩坑笔记
前端
好好沉淀4 小时前
1.13草花互动面试
面试·职场和发展
南村群童欺我老无力.4 小时前
Flutter应用鸿蒙迁移实战:性能优化与渐进式迁移指南
javascript·flutter·ci/cd·华为·性能优化·typescript·harmonyos