iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >react context优化的方法有哪些
  • 867
分享到

react context优化的方法有哪些

2023-07-04 11:07:59 867人浏览 薄情痞子
摘要

本篇内容介绍了“React context优化的方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、前言我们在使用reac

本篇内容介绍了“React context优化的方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    一、前言

    我们在使用react的过程中,经常会遇到需要跨层级传递数据的情况。props传递数据应用在这种场景下会极度繁琐,且不利于维护,于是context应运而生

    官方解释: Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props

    二、用法

    在正文之前,先简单介绍一下context的三种消费方法:

    • 通过Consumer来消费上下文

    const globalContext = React.createContext();class TestUseContextSon1 extends React.Component {  render() {    return (      <globalContext.Consumer>        {(value) => {          return <div>{value.num}</div>;        }}      </globalContext.Consumer>    );  }}export default class TestUseContext extends React.Component {  constructor(props) {    super(props);    this.state = {      num: 2,    };  }  render() {    return (      <globalContext.Provider value={{ num: this.state.num }}>        <TestUseContextSon1 />      </globalContext.Provider>    );  }}
    • 通过静态变量contextType来消费上下文

    const globalContext = React.createContext();class TestUseContextSon2 extends React.Component {  static contextType = globalContext;  render() {    return <div>{this.context.num}</div>;  }}export default class TestUseContext extends React.Component {  ...省略...  render() {    return (      <globalContext.Provider value={{ num: this.state.num }}>        <TestUseContextSon2 />      </globalContext.Provider>    );  }}
    • 通过hooks useContext来消费上下文

    const globalContext = React.createContext();const TestUseContextSon3 = (props) => {  const con = useContext(globalContext);  return <div>{con.num}</div>;};export default class TestUseContext extends React.Component {  ...省略...  render() {    return (      <globalContext.Provider value={{ num: this.state.num }}>        <TestUseContextSon3 />      </globalContext.Provider>    );  }}

    比较:

    • Consumer既可以在类组件中使用,也可以在函数组件中使用

    • contextType只能在类组件中使用

    • useContext只能在函数组件中使用

    三、缺点

    这里有一个例子:

    import React, { useState } from "react";const globalContext = React.createContext();const Son1 = () => {  return <div>Son1</div>;};const Son2 = () => {  const value = useContext(globalContext);  return <div>Son2---{value.num}</div>;};export const Demo = () => {  const [value, setValue] = useState({ num: 1 });  return (    <globalContext.Provider value={value}>      <Son1 />      <Son2 />    </globalContext.Provider>  );};

    当我们改变value值时,会导致Son1Son2都发生重渲染,但这与我们的初衷相悖,造成了额外的开销,我们期望做到的是Son1不执行,Son2重新渲染。在较长的一段时间内,我都认为是使用了context导致Provider下面的子组件发生了重渲染。网上也有很多解释没有说清楚,容易误导人。

    实际情况是value的变化导致了Son1Son2发生重渲染。如下示例: 即使我们不使用&middot;context,当value发生变化时,Son1Son2也会重渲染。

    const Son1 = () => {  return <div>Son1</div>;};const Son2 = () => {  return <div>Son2</div>;};export const Demo = () => {  const [value, setValue] = useState({ num: 1 });  return (    <Son1 />    <Son2 />  );};

    那么问题来了,我们使用context的时候,必然要向<globalContext.Provider value={value}>Provider的value中传入一个状态,但是当状态改变时又不可避免的造成Provider下的所有子组件重新渲染,我们期望只有消费了上下文的子组件重新渲染,那么有什么方法能够避免这种额外的开销吗?

    四、context优化

    我们知道,所有消费了context的地方,只要Providervalue值发生变化,都会发生重渲染.只要我们有什么办法能够避开父组件状态发生变化,引起的子组件状态发生变化,那就可以减少很多不必要的开销。

    一重奏--使用PureComponent

    const globalContext = React.createContext();class TestUseContextSon2 extends React.PureComponent {  constructor(props) {    super(props);    this.state = {};  }  render() {    console.log("TestUseContextSon2----render");    return (      <globalContext.Consumer>        {(value) => {          console.log("Consumer----handle");          return <div>{value.num}</div>;        }}      </globalContext.Consumer>    );  }}const TestUseContext = () => {  const [value, setValue] = useState({ num: 1 });  return (      <globalContext.Provider value={value}>        <button onClick={() => setValue({ num: value.num + 1 })}>          点击        </button>        <TestUseContextSon2 />      </globalContext.Provider>  );}

    react context优化的方法有哪些

    初始化的时候,两个console各执行一遍

    react context优化的方法有哪些

    点击按钮之后,TestUseContextSon2----render没有打印,Consumer----handle打印,达到预期结果。

    二重奏--使用shouldComponentUpdate

    此处由于作者比较任性,省略100字,基本效果其实和PureComponent一致,不做过多描述。

    三重奏--使用React.memo

    React.memo既可以用于函数组件,也可以用于类组件

    const globalContext = React.createContext();const TestUseContextSon3 = React.memo(function (props) {  console.log("TestUseContextSon3----render");  return (      <globalContext.Consumer>        {(value) => {          console.log("Consumer----handle");          return <div>{value.num}</div>;        }}      </globalContext.Consumer>    );});const TestUseContext = () => {  const [value, setValue] = useState({ num: 1 });  return (      <globalContext.Provider value={value}>        <button onClick={() => setValue({ num: value.num + 1 })}>          点击        </button>        <TestUseContextSon3 />      </globalContext.Provider>  );}

    react context优化的方法有哪些

    点击按钮之后,TestUseContextSon2----render没有打印,Consumer----handle打印,达到预期结果。 那如果我们使用useContext来消费上下文呢?

    const TestUseContextSon4 = React.memo(function (props) {  const con = useContext(globalContext);  console.log("TestUseContextSon4----render");  return &lt;div&gt;{con.num}&lt;/div&gt;;});

    react context优化的方法有哪些

    点击按钮之后,TestUseContextSon4----render打印,也就是说当我们使用useContext来消费上下文的时候,整个函数组件会重新执行。而Consumer仅仅只是局部执行,这意味更少的性能消耗。

    四重奏--Provider再封装+props.children

    上面所述的三种方法都存在一个弊端,Provider的直接下级组件都需要用memoPureComponentshouldComponentUpdate处理,才能屏蔽掉父级状态变化带来的影响,那么有没有一种更方便的方式呢?

    代码如下:

    const ThemeContext = React.createContext({ theme: "red" });const ThemeProvider = (props) => {  const [theme, setTheme] = useState({ theme: "red" });  console.log("ThemeProvider-----", theme.theme);  return (    <ThemeContext.Provider value={{ theme, setTheme }}>      {props.children}    </ThemeContext.Provider>  );};const Son1 = function (props) {  const { setTheme } = useContext(ThemeContext);  return <button onClick={() => setTheme({ theme: "blue" })}>改变主题</button>;};const Son2 = function (props) {  const { theme } = useContext(ThemeContext);  console.log("Son2----", theme.theme);  return <div>主题----{theme.theme}</div>;};const Son4 = function (props) {  console.log("Son4---没有使用上下文");  return <div>没有使用上下文</div>;};export default class ContextChildren extends React.Component {  render() {    return (      <ThemeProvider>        <Son1 />        <Son2 />        <Son4 />      </ThemeProvider>    );  }}

    在上面这段代码中,<Son1 /><Son2 /><Son3 />并没有直接放到ThemeContext.Provider组件下面,而是将该组件再次封装成ThemeProvider组件,并将状态管理也放在ThemeProvider组件中,然后通过props.children来引入组件子节点。

    效果如下:

    react context优化的方法有哪些

    当我们点击按钮时,打印如下:

    react context优化的方法有哪些

    点击按钮,setTheme执行,状态由{ theme: "red" }变为{ theme: "blue" },引起ThemeProvider组件重新执行,打印ThemeProvider----- blue,组件Son2由于消费了上下文,重新执行,打印Son2---- blue

    那么问题来了,为什么没有打印Son4呢?我们没有使用memo、PureComponent等处理Son4组件,但是它确实不会重新执行。

    出现这种现象,其实是props.children引起的,props.children指向一个对象,这个对象中存放着<Son1 /><Son2 /><Son3 />执行的结果,ThemeProvider执行的时候,props.children指向的对象没有发生变化,只有当ContextChildren组件重新渲染的时候,<Son1 /><Son2 /><Son3 />才会重新执行,由于我们将状态放置于ThemeProvider组件中,所以ContextChildren组件不会重新渲染,<Son1 /><Son2 /><Son3 />也就不会重新执行,所以Son4---没有使用上下文没有打印。

    那如果将ThemeProvider组件改成这样呢?

    const ThemeProvider = (props) => {  const [theme, setTheme] = useState({ theme: "red" });  console.log("ThemeProvider-----", theme.theme);  const content = React.Children.map(props.children, (child) => {    return child;  });  return (    <ThemeContext.Provider value={{ theme, setTheme }}>      {content}    </ThemeContext.Provider>  );};

    Son4依然没有执行

    react context优化的方法有哪些

    再改一下:

    const ThemeProvider = (props) => {  const [theme, setTheme] = useState({ theme: "red" });  console.log("ThemeProvider-----", theme.theme);  const content = React.Children.map(props.children, (child) => {    return React.cloneElement(child);  });  return (    <ThemeContext.Provider value={{ theme, setTheme }}>      {content}    </ThemeContext.Provider>  );};

    我们使用React.cloneElementapi克隆一下child

    react context优化的方法有哪些

    Son4执行了,我想这是因为克隆之后指向发生变化,导致组件重新执行

    “react context优化的方法有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

    --结束END--

    本文标题: react context优化的方法有哪些

    本文链接: https://www.lsjlt.com/news/344717.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • react context优化的方法有哪些
      本篇内容介绍了“react context优化的方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、前言我们在使用reac...
      99+
      2023-07-04
    • react性能优化的方法有哪些
      1. 使用生命周期方法:React的生命周期方法可以帮助我们优化组件的性能。例如,使用shouldComponentUpdate方法...
      99+
      2023-09-13
      react
    • 简化React Hook的方法有哪些
      这篇文章主要讲解了“简化React Hook的方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“简化React Hook的方法有哪些”吧!1. 减少 ...
      99+
      2024-04-02
    • context对象的方法有哪些
      这篇文章主要介绍了context对象的方法有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇context对象的方法有哪些文章都会有所收获,下面我们一起来看看吧。API 接口方法说明createCanvasC...
      99+
      2023-06-26
    • 有哪些优化MySQL的方法
      这篇文章给大家分享的是有关有哪些优化MySQL的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。MySQL优化1.优化索引、SQL语句、分析慢查询;2.设计表的时候严格按照数据...
      99+
      2024-04-02
    • mysql优化的方法有哪些
      使用索引:在经常使用的列上创建索引可以提高查询速度。需要注意的是不要过度索引,否则会影响写操作的性能。 优化查询语句:避免使...
      99+
      2024-04-16
      mysql
    • mysql的优化方法有哪些
      本篇内容主要讲解“mysql的优化方法有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql的优化方法有哪些”吧!目前项目性能指标是20万用户,20并发...
      99+
      2024-04-02
    • 优化MySQL的方法有哪些
      这篇文章主要介绍了优化MySQL的方法有哪些,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。1、选取最适用的字段属性MySQL可以很好的支持大数据...
      99+
      2024-04-02
    • Hive优化的方法有哪些
      Hive优化方法主要包括以下几个方面: 数据分区和桶排序:通过将数据分成多个分区,可以减少查询的数据量,提高查询性能。此外,使用...
      99+
      2023-10-22
      Hive
    • 有哪些SQL优化方法
      这篇文章主要介绍“有哪些SQL优化方法”,在日常操作中,相信很多人在有哪些SQL优化方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”有哪些SQL优化方法”的疑惑有所帮助!接...
      99+
      2024-04-02
    • sql有哪些优化方法
      小编给大家分享一下sql有哪些优化方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.对查询进行优化,应尽量避免全表扫描,首先...
      99+
      2024-04-02
    • SQL优化方法有哪些
      这篇文章主要讲解了“SQL优化方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL优化方法有哪些”吧!一、避免进行null判断 &nbs...
      99+
      2024-04-02
    • clickhouse sql优化的方法有哪些
      点击豪斯(ClickHouse)是一个列式存储的数据库管理系统,专门用于大规模分布式数据处理。以下是一些ClickHouse SQL...
      99+
      2023-10-23
      clickhouse sql
    • Hibernate HQL优化的方法有哪些
      这篇文章主要讲解了“Hibernate HQL优化的方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Hibernate HQL优化的方法有哪些”吧!初用Hibernate的人也许都遇...
      99+
      2023-06-17
    • mysql中有哪些优化方法
      mysql中有哪些优化方法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1、sql优化分解关联查询:将关联(join)放在应用中处理,执行简单的sql,好处是:分解后的sq...
      99+
      2023-06-15
    • 有哪些React性能优化工具
      这篇文章主要讲解了“有哪些React性能优化工具”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“有哪些React性能优化工具”吧! Profiler...
      99+
      2024-04-02
    • APK结构优化的方法有哪些
      这篇文章主要介绍“APK结构优化的方法有哪些”,在日常操作中,相信很多人在APK结构优化的方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”APK结构优化的方法有哪些”的疑惑有所帮助!接下来,请跟着小编...
      99+
      2023-06-04
    • JavaScript性能优化的方法有哪些
      这篇文章主要讲解了“JavaScript性能优化的方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript性能优化的方法有哪些”吧! ...
      99+
      2024-04-02
    • Java技能的优化方法有哪些
      这篇文章主要讲解了“Java技能的优化方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java技能的优化方法有哪些”吧!1         通...
      99+
      2023-06-17
    • win10优化设置的方法有哪些
      本文小编为大家详细介绍“win10优化设置的方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“win10优化设置的方法有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。win10优化设置方法:用360优...
      99+
      2023-07-01
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作