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)
相关推荐
Bigger20 分钟前
从零搭建 AI 代码审查服务:一份前端也能看懂的 Python 学习笔记
前端·ci/cd·ai编程
lichenyang45337 分钟前
JSAPI、NAPI、Biz、Imp:ASCF Demo 如何真正调用系统能力和 C++ 能力
前端
自由路飞1 小时前
RAG 混合检索深挖:BM25 和向量分数为什么不能直接相加?
面试
lichenyang4531 小时前
IPC、JSVM、UIThread、libuv:ASCF 架构图里最容易混的几个词
前端
用户059540174461 小时前
Redis记忆存储故障恢复测试踩坑实录:手动测试让我漏掉了2个一致性Bug
前端·css
用户2136610035721 小时前
Vue2脚手架工程化与Axios集成
前端·vue.js
未秃头的程序猿1 小时前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
张元清1 小时前
React useDebounce Hook:给状态和回调做防抖(2026)
javascript·react.js
我不是外星人1 小时前
我把 Claude Code 搬到网页!自研高颜值 Web 交互工作台
前端·ai编程·claude
mixuecoding1 小时前
零成本搭建全球科技热点情报站:12 个平台,6 小时,0 元
前端