React:隐藏与删除组件

Iva*_*nko 21 javascript dom reactjs

这个问题更多的是关于架构而不是编码。

案例如下。在 React 中有时我们想要隐藏组件。例如,当用户在 SPA 中打开新页面时,当某些 toast 关闭时等。我们可以通过添加 来隐藏它们display: none。或者我们可以从虚拟 DOM 中删除它们。

// Hidden div
<div style={{ display: 'none' }}/>

// Removed div
{false && <div/>}
Run Code Online (Sandbox Code Playgroud)

我们的一些老年人也使用第一种变体。即使他们隐藏整个页面。他们对此方法是这么说的:“这种情况下 React 预渲染了所需的内容,因此当内容必须出现时,它需要更少的时间”。

但在这种情况下,我们不能使用生命周期钩子,因为即使组件隐藏,它也不会被删除。但我认为主要的问题是真实的 DOM 变得巨大。这会带来缓慢,不是吗?

那么,什么是更好的呢?


我没有找到任何关于这个问题的对话。也许你可以帮助我。


编辑1:尽管事实上有一些答案,但我想知道更多的意见。所以,我决定开放赏金

Yev*_*kov 15

注意:对于那些对冗长的解释不感兴趣的人(试图获得代表赏金),后面是不相关的例子和阴谋,这里有一个快速的解释

长话短说

您需要根据自己具体用例来决定。

需要牢记的注意事项

  • 构建渲染树时会忽略隐藏的 DOM 元素,因此通过样式控制可见性时您可能看到的唯一性能增益可能是由于提前构建 DOM 树造成的。

  • 当可见性由样式设置控制时,过多的 DOM 大小可能会不必要地减慢浏览器的速度。

  • 另一方面,从 React 的角度来看,应用条件渲染(并重建后代树,一旦您决定使它们可见)似乎比更改单个属性稍微昂贵一些。

考虑到上述情况,对于访问几率相对较高(或在用户交互过程中大部分时间显示)的复杂组件(大型 DOM 子树),切换可见性样式是有意义的。否则,从性能的角度来看,条件渲染似乎是更好的选择。

ps:除了性能之外,您可能还关心

  • SEO - 如果您有条件地渲染一些导航面板/对话框,其中包含指向应用程序其他页面的链接,这些链接不会出现在您的 DOM 中,因此不能被爬虫遍历并建立索引,这不会是如果您使用样式设置切换可见性;
  • UX - 如果根据设计,UI 元素在屏幕上出现/消失必须有动画(例如淡入/淡出),如果您使用条件渲染,您可能需要更先进的技术来确保动画仍然有效,不会让您的用户感到沮丧
  • display: none辅助功能 -屏幕阅读器仍可访问隐藏在视图中的 UI 部分


Ste*_*n J 12

让我们比较一下这两种切换 HTML 元素可见性、元素切换(又名display: none|block)和JSX 短路渲染方法之间的一些差异

  1. 简单性- 如您所知,JSX 已针对反应式切换标记进行了优化,因此它不会打印falsetruenullundefined,因此您可以在其中编写更短的逻辑。Facebook https://facebook.github.io/jsx/#why-not-template-literals带来了类似的不使用模板文字而不是 JSX 的情况。简单性带来可维护性,从长远来看,它将帮助您的应用程序不会成为另一个意大利面条废话。
  isShown && <div />
Run Code Online (Sandbox Code Playgroud)

 <div style={{ display: isShown ? 'block' : 'none' }} />
Run Code Online (Sandbox Code Playgroud)
  1. 性能- 跨越更多节点对性能和内存使用永远不会有好处,通常每个应用程序都会有所不同。可以使用 Chrome 的性能监视器或 React Profiler 对其进行基准测试。但更重要的是,React 围绕您将遵循https://reactjs.org/docs/jsx-in-depth.html而不是使用其他技巧的知识构建了新的性能优化。鉴于您的部分或大部分代码库正在使用该element toggling方法,并且有一个具有性能改进的新版本的 React,您可能会花费数周的时间进行重构才能从中受益。

  2. 错误- 使用 JSX 短路渲染时,您必须记住不要使用类似于数组没有成员的elements.length && elements.map(({ text }) => text)情况,JSX 将打印 0 而不是什么都不打印。elements另一方面,设置可见性几乎display: block肯定会导致flex,,,元素被设置为。第二个错误更难发现,因为您需要处理 css 样式或 css-in-js。inlineinline-blocktableblock

  3. 一致性- 鉴于 JSX 短路渲染是 React 维护者推荐的方法,它将出现在大多数 React 项目中。但是如果您将其与旧式显示切换方法混合使用,任何加入团队的新开发人员都会质疑您为什么同时使用这两种方法。混合这些很可能会导致错误,其中元素可能会被 JSX 显示,同时会被隐藏,display: none反之亦然。

  4. 调试- 使用 React Devtools 或 Elements,同时设置大量元素display: none是一场噩梦,因为它会被您根本不需要的节点污染

我认为高级开发人员习惯于切换元素,display因为它被认为是老派。这也可能是您的应用程序从 jQuery 转换为 React 的遗留问题。这是当时制作 UI 的唯一方法。有些习惯或者我应该说心理模型是相当粘的。现在,在 React 项目中,我将把上面的内容视为 hack。

我建议不要使用任何其他方式来切换 React 中标记的可见性,但标准JSX 短路渲染 isShown && <div />除外。根据我编写 React 应用程序的长期经验,我尝试坚持使用最简单、最具表现力的代码,所有开发人员(从大学毕业生到大三学生、大四学生)都会期望按照最佳实践,并且不会在阅读上遇到困难,因此他们会重用这些代码比编写同一组件的第 n 个版本要好。

编辑:正如其他答案中提到的,过渡动画通常是使用仅适用于 JSX 短路渲染的react-transition-group 包来完成的。