react 【context在函数组件和class组件中的使用】

前言

  在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。

  可以访问的生命周期

  class组件

    在shouldComponentUpdate之后访问,constructor和getDeriverdStateFromProps中无法访问到

  函数组件

    函数组件通过hook访问

更新规则

  当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。Provider 及其内部 consumer 组件都不受制于 shouldComponentUpdate 函数,因此当 consumer 组件在其祖先组件退出更新的情况下也能更新。

  通过新旧值检测来确定变化,使用了与 Object.is 相同的算法。

涉及api

  react.createContext:context函数

  

  <Context.Provider>:组件元素,被包裹的组件可以及其子元素可以通过contextType消费context

  

  Class.contextType:指定消费context,必须要是被<Context.Provider>包裹的元素

  

  Context.Consumer:指定消费context,和Class.contextType作用一致,区别是此方法适用于函数组件。 与Context.Provider不同的是,Context.Provider可以嵌套使用,而Context.Consumer的children必须是一个函数组件

  ps:函数组件推荐使用hook useContext,此方法或许在后续版本会被移除.

  

  Context.displayName:定义context在devtools中的别名配合调试工具使用

  

涉及hook

  useContext

案例代码

  class

//创建一个context
const MyContext = react.createContext("init");

//祖先组件
const ancestor = () => {
  return (
    <div>
      <h2>ancestor</h2>
      <div>
        <MyContext.Provider value={"context value"}>
          //包裹子组件
          <Son />
        </MyContext.Provider>
      </div>
    </div>
  );
};

//子组件
const Son = () => {
  return (
    <div>
      <h2>son</h2>
      <div>
        <Grandson /> //孙组件
      </div>
    </div>
  );
};

//孙组件
class Grandson extends react.Component {
  //注入context 在class组件中,必须要为static属性contextType,设置通过react.createContext()创建的context对象,才能使用this.context,不然this.context的值会为一个{}
  static contextType = MyContext;

  componentDidMount() {
    console.log(this.context); //context value
  }
  render() {
    return (
      <div>
        <h2>grandson</h2>
        <div>
          <span>获取的context值:</span>
        </div>
      </div>
    );
  }
}
View Code

  函组件

const Son = (props: any) => {
  const context: any = useContext(MyContext); //通过hook useContext指定消费Context,
  console.log("son", context); //
  return (
    <div>
     {/* 其他输出 */}
    </div>
  );
};

 

 

 

 

posted @ 2022-01-20 16:15  眼里有激光  阅读(1320)  评论(0编辑  收藏  举报