• react中Context以及useContext的使用


    解决问题:在较深的组件树中如何进行数据的传递

    Why:提出context的初衷

    react中的数据在父子组件中一般以props形式传递,如果父组件要把某个数据传递给孙子或者重孙子组件,就要经过子组件层层传递,比较麻烦。为此引入context全局上下文,来实现数据跨组件共享

    When:context的使用场合

    • 传给多个孙子组件
      推荐使用全局上下文,避免属性层层传递到多个孙子组件
      但也有副作用:组件的复用性变差
    • 传给单个孙子组件
      不建议使用context
      替代方案:如果是想避免多个属性层层传递给孙子组件,可以将直接孙子组件自身传递下去,那么中间组件就无需知道多余的props
      替代方案评价:
      好处:减少传递props数量,代码更干净
      坏处:逻辑提升到组件树的更高层级处理,高层组件变得复杂

    How:如何使用context

    🌰举例:设置主题色:黑色/白色
    生产侧代码:useTheme.tsx文件⬇️

    // 1 创建主题色上下文
    const ThemeContext = React.createContext(undefined);
    ThemeContext.displayName = 'ThemeContext';
    
    // 2 创建Provider,同时设定value
    // context会根据引用标识决定何时进行渲染,所以一个陷阱🪤,provider的父组件重新渲染时,可能会在consumers组件中触发意外的渲染
    // 为了防止这种情况,需要将value状态提升到父节点的state中
    const ThemeProvider = (children) => {
      const [theme, setTheme] = useState('light');
    
      return <ThemeContext.Provider value={theme, setTheme}>
        { children }
      </ThemeContext.Provider>
    }
    
    // 3 创建hooks
    const useTheme = () => {
      const context = useContext(themeContext);
      if(!context){
        throw new Error ('useTheme必须在ThemeProvider中使用')
      }
    
      return context;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    消费侧代码:
    首先作为Provider的子组件使用

    <Themeprovider>
      <ThemeBar/>
    </Themeprovider>
    
    • 1
    • 2
    • 3

    其中ThemeBar中可以拿到全局数据theme

    import React from 'react';
    
    // theme变化,ThemeBar就重新渲染,所以不建议把很多属性耦合进入同一个Context中
    // 要把经常变化的和不经常变化的分开,例如:ThemeContext就负责Theme
    const ThemeBar = () => {
      const {theme, setTheme} = useTheme();
    
    	return <div onClick={()=>setTheme('dark')}>{theme}<div>
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Tips:性能浪费

    当Provider的value变化时,内部所有消费组件都会重新渲染,并且useContext的传播不会受制于shouldComponentUpdate函数,所以父亲组件用了memo,但子组件是context的消费组件,当value变化时,也会重新渲染

  • 相关阅读:
    Windows10下Git2.37.1安装及配置完整版
    AMD-Xilinx技术日 信息汇总(1)
    vue elementUI table表格自定义样式滚动
    Netty-SocketIo 完美替换 nodejs 的 socketio
    TCP流套接字编程
    火山引擎 RTC 自研音频编码器 NICO 实践之路
    Three光线投射实例
    spring自动装配servlet
    教您简单几步实现工业树莓派正确安装RS232转USB驱动
    minio集群部署(k8s内)
  • 原文地址:https://blog.csdn.net/qq_36154157/article/details/127910448