React学习笔记——context

390 阅读2分钟

context 基本使用

context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。context 对象提供两个组件,Provider和 Consumer作为提供者和消费者,但是必须注意一点是,提供者永远要在消费者上层,正所谓水往低处流,提供者一定要是消费者的某一层父级。

1.createContext 创建

const GlobalContext = React.createContext(null) //
const GlobalProvider = GlobalContext.Provider //提供者 
const GlobalConsumer = GlobalContext.Consumer // 订阅消费者
export const GlobalContext = React.createContext<IGlobalContext>({
  logged: false,
  abTest: "A",
});
return (
    <>
        <GlobalContext.Provider value={{ logged, abTest }}>
          <Routes />
        </GlobalContext.Provider>
    </>
  );

类组件之contextType 方式 获取

class Leaf extends Component {
  static contextType = GlobalContext;
  
  render() {
    const battery = this.context;
    return<h1>Battery : {battery}</h1>
  }
}

  • contextType为静态属性;
  • this.context就可以获取context属性值了
  • contextType 只能在类组件中使用
  • 一个组件如果有多个 consumer , contextType 只对其中一个有效,所以说,contextType 只能有一个

函数组件之 useContext 方式 获取

useContext 接受一个参数,就是想要获取的 context ,返回一个 value 值,就是最近的 provider 提供 contextValue 值。

import { useContext } from "react";
import { GlobalContext } from "@/pages";

/**
 * @return abTest AbTest状态
 */
function useAbTest(): string {
  const { abTest } = useContext(GlobalContext);
  return abTest;
}
export default useAbTest;

订阅者之 Consumer 方式 获取

  • Consumer 订阅者采取 render props 方式,接受最近一层 provider 中value 属性,作为 render props 函数的参数,可以将参数取出来,作为 props 混入 ConsumerDemo 组件,说白了就是 context 变成了 props。
class Bottom extends React.Component {
  render () {
    return (
      // Context.Consumer Consumer消费者使用Context得值
      // 但子组件不能是其他组件,必须渲染一个函数,函数的参数就是Context得值
      <GlobalContext.Consumer>
        {
          ({logged,abTest}) => <h1>GlobalContext 的 值为 {logged},{abTest}</h1>
        }
      </GlobalContext.Consumer>
    )
  }
}

context 作用

context解决了:

  • 解决了 props 需要每一层都手动添加 props 的缺陷。
  • 解决了改变 value ,组件全部重新渲染的缺陷。

react-redux 就是通过 Provider 模式把 redux 中的 store 注入到组件中的。

context 小技巧

  1. 嵌套 Provider
  2. 逐层传递Provider
  • 全局只有一个 ThemeContext ,两次用 provider 传递两个不同 context 。
  • 组件获取 context 时候,会获取离当前组件最近的上一层 Provider 。
  • 下一层的 provider 会覆盖上一层的 provider 。

3.context中还可以传递方法

export default function (){
    const [ themeContextValue ,setThemeContext ] = React.useState(theme.dark) 
    /* 传递颜色主题 和 改变主题的方法 */
    return <ThemeContext.Provider value={ { ...themeContextValue, setTheme:setThemeContext  } } >
        <App/>
    </ThemeContext.Provider>
}