• react源码分析:深度理解React.Context


    开篇

    在 React 中提供了一种「数据管理」机制:React.context,大家可能对它比较陌生,日常开发直接使用它的场景也并不多。

    但提起 react-redux 通过 Providerstore 中的全局状态在顶层组件向下传递,大家都不陌生,它就是基于 React 所提供的 context 特性实现。

    本文,将从概念、使用,再到原理分析,来理解 Context 在多级组件之间进行数据传递的机制。

    一、概念

    Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。

    通常,数据是通过 props 属性自上而下(由父到子)进行传递,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。

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

    设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。

    二、使用

    下面我们以 Hooks 函数组件为例,展开介绍 Context 的使用。

    2.1、React.createContext

    首先,我们需要创建一个 React Context 对象。

    const Context = React.createContext(defaultValue);
    
    • 1

    当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中的 Context.Provider 中读取到当前的 context.value 值。

    当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。

    2.2、Context.Provider

    每个 Context 对象都会返回一个 Provider React 组件,它接收一个 value 属性,可将数据向下传递给消费组件。当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。

    注意,当 value 传递为一个复杂对象时,若想要更新,必须赋予 value 一个新的对象引用地址,直接修改对象属性不会触发消费组件的重渲染。

    <Context.Provider value={
       /* 某个值,一般会传递对象 */}>
    
    • 1
    • 2

    2.3、React.useContext

    Context Provider 组件提供了向下传递的 value 数据,对于函数组件,可通过 useContext API 拿到 Context value

    const value = useContext(Context);
    
    • 1

    useContext 接收一个 context 对象(React.createContext 的返回值),返回该 context 的当前值。

    当组件上层最近的 更新时,当前组件会触发重渲染,并读取最新传递给 Context Provider 的 context value 值。

    题外话:React.memo 只会针对 props 做优化,如果组件中 useContext 依赖的 context value 发生变化,组件依旧会进行重渲染。

    2.4、Example

    我们通过一个简单示例来熟悉上述 Context 的使用。

    const Context = React.createContext(null);
    
    const Child = () => {
       
      const value = React.useContext(Context);
      return (
        <div>theme: {
       value.theme}</div>
      )
    }
    
    const App = () => {
       
      const [count, setCount] = React.useState(0);
      return (
        <Context.Provider value={
       {
        theme: 'light' }}>
          <div onClick={
       () => setCount(count + 1)}>触发更新</div>
          <Child />
        </
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    浅谈城市综合管廊分类及其运维管理-Susie 周
    QT控件 — QScrollArea
    MySQL视图详解
    克鲁斯卡尔算法(C++)
    第57篇 QML 之 JS 数据类型详解(必看)
    迁移Linux服务器用户数据(将一个服务器的Linux用户数据迁移到另一个Linux服务器用户的流程)
    spring boot中的标注@Component、@Service等
    ArcGIS 10.7软件安装包下载及安装教程!
    几十年工作经验总结微服务体系建设和实践,干货满满
    详解风控模型中的逻辑回归评分卡与模型评估内容
  • 原文地址:https://blog.csdn.net/weixin_59558923/article/details/127764583