React 组件的状态下移和内容提升的操作方法

 更新时间:2022年11月26日 15:06:41   作者:前端小二哥  
这篇文章主要介绍了React 组件的状态下移和内容提升,通过代码讲解了渲染性能的组件问题结合实例代码给大家讲解的非常详细,需要的朋友可以参考下

前言

本专栏的另一篇文章,讲到了 useMemo 有一定的开销,不能滥用,本篇文章讲解两个简单实用的优化组件渲染性能的方法:

  • 状态下移
  • 内容提升

在讲解这两种方法之前,我们需要先手动创建一个有严重渲染性能的组件,如下所示:

import { useState } from 'react';

export default function App() {
  let [color, setColor] = useState('red');
  return (
    <div>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p style={{ color }}>Hello, world!</p>
      <ExpensiveTree />
    </div>
  );
}

function ExpensiveTree() {
  let now = performance.now();
  while (performance.now() - now < 100) {
    // Artificial delay -- do nothing for 100ms
  }
  return <p>I am a very slow component tree.</p>;
}

很显然,当 App 组件内的状态发生了改变,ExpensiveTree 组件会 re-render, 事实上 ExpensiveTree 组件的 props、state 并未发生改变,这并不是我们期望的结果,下面将提供两种简单的方法,提升组件渲染的性能;

状态下移

export default function App() {
  let [color, setColor] = useState('red');
  return (
    <div>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p style={{ color }}>Hello, world!</p>
      <ExpensiveTree />
    </div>
  );
}

我们可以看到以上 ExpensiveTree 组件并不依赖 App 组件内部的状态,因此我们是否可以考虑,将依赖 color 的元素抽离到一个依赖 color 的组件中呢?
下面是实践后的代码:

export default function App() {
  return (
    <>
      <Form />
      <ExpensiveTree />
    </>
  );
}

function Form() {
  let [color, setColor] = useState('red');
  return (
    <>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p style={{ color }}>Hello, world!</p>
    </>
  );
}

此时,将依赖 color 的元素提取到了 Form 组件中,Form 组件内部的状态不再影响 ExpensiveTree 组件的渲染,问题便得到了解决

内容提升

export default function App() {
  let [color, setColor] = useState('red');
  return (
    <div style={{ color }}>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p>Hello, world!</p>
      <ExpensiveTree />
    </div>
  );
}

以上情况是高开销组件 ExpensiveTree 的父节点依赖 color,此时显然状态下移是行不通的,但是还有另外一种办法:

export default function App() {
  return (
    <ColorPicker>
      <p>Hello, world!</p>
      <ExpensiveTree />
    </ColorPicker>
  );
}

function ColorPicker({ children }) {
  let [color, setColor] = useState("red");
  return (
    <div style={{ color }}>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      {children}
    </div>
  );
}

此时和状态提升是完全相反的,将依赖 color 的元素提升到了 ColorPicker 组件中,而不依赖 color 的元素以 children prop 的形式传入了 ColorPicker ,当组件内部的状态改变时:

  • ColorPicker 会重新渲染但是它仍然保存着
  • ColorPicker 的 children 属性未变化 React 并不会访问那棵子树。 因此,ExpensiveTree不会重新渲染。

本文提供的方法并不是新的创意,大家一定都有所实践,但是我想表达的是,相比于滥用 useMemo,我们需要首先考虑使用这两种提高组件渲染性能的方法;

到此这篇关于React 组件的状态下移和内容提升的文章就介绍到这了,更多相关React 组件状态下移内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React 项目中动态设置环境变量

    React 项目中动态设置环境变量

    本文主要介绍了React 项目中动态设置环境变量,本文将介绍两种常用的方法,使用 dotenv 库和通过命令行参数传递环境变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • React中使用Axios发起POST请求提交文件方式

    React中使用Axios发起POST请求提交文件方式

    这篇文章主要介绍了React中使用Axios发起POST请求提交文件方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • react-router 路由切换动画的实现示例

    react-router 路由切换动画的实现示例

    这篇文章主要介绍了react-router 路由切换动画的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • React教程之Props验证的具体用法(Props Validation)

    React教程之Props验证的具体用法(Props Validation)

    这篇文章主要介绍了React教程之Props验证的具体用法(Props Validation),非常具有实用价值,需要的朋友可以参考下
    2017-09-09
  • React 错误边界组件的处理

    React 错误边界组件的处理

    这篇文章主要介绍了React 错误边界组件的处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • React 组件的状态下移和内容提升的操作方法

    React 组件的状态下移和内容提升的操作方法

    这篇文章主要介绍了React 组件的状态下移和内容提升,通过代码讲解了渲染性能的组件问题结合实例代码给大家讲解的非常详细,需要的朋友可以参考下
    2022-11-11
  • react使用antd的上传组件实现文件表单一起提交功能(完整代码)

    react使用antd的上传组件实现文件表单一起提交功能(完整代码)

    最近在做一个后台管理项目,涉及到react相关知识,项目需求需要在表单中带附件提交,怎么实现这个功能呢?下面小编给大家带来了react使用antd的上传组件实现文件表单一起提交功能,一起看看吧
    2021-06-06
  • React中useEffect Hook常见问题及解决

    React中useEffect Hook常见问题及解决

    React的useEffect Hook它允许我们在函数组件中执行副作用操作,但在使用过程中可能会遇到一些常见的错误,本文就来介绍一下常见问题及解决,感兴趣的可以了解一下
    2023-10-10
  • 深入浅析react native es6语法

    深入浅析react native es6语法

    这篇文章主要介绍了深入浅析react native es6语法的相关资料,需要的朋友可以参考下
    2015-12-12
  • React Hooks--useEffect代替常用生命周期函数方式

    React Hooks--useEffect代替常用生命周期函数方式

    这篇文章主要介绍了React Hooks--useEffect代替常用生命周期函数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论