Skip to main content

React Context 跨级传参

Context 提供了一个局部的全局作用域,使用 Context 则无需再手动的逐层传递 props。

一、Context 的使用

1、createContext + contextType

可以通过 Class.contextType 直接将 Context 对象挂载到 class 的 contextType 属性,然后就可以使用 this.context 对 context 对象进行使用。举个设置主题 theme 的例子:

  • 使用 Context 前:
import React from 'react'

const Father = () => {
return <Child theme="dark" />
}

const Child = (props) => {
return <GrandChild theme={props.theme} />
}

class GrandChild extends React.Component {
render() {
return <div>{this.props.theme}</div>
}
}

export default Father
  • 使用 Context 后:
import React from 'react'

// 为 theme 创建一个 Context(默认值为 light)
const ThemeContext = React.createContext('light')
const Father = () => {
// 使用 Provider 将当前的 theme 传递给以下的组件树
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
)
}

// 中间的组件就不用层层往下传递 theme 了
const Child = () => {
return <GrandChild />
}

class GrandChild extends React.Component {
// 指定 contextType 读取当前的 theme context
// React 会往上找到最近的 theme Provider,然后使用它的值 dark
static contextType = ThemeContext
render() {
return <div>{this.context}</div>
}
}

export default Father

2、createContext + Consumer

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

import React from 'react'

const ThemeContext = React.createContext('light')
const Father = () => {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
)
}

const Child = () => {
return <GrandChild />
}

const GrandChild = () => {
// 使用 Consumer 基于 context 值进行渲染
return (
<ThemeContext.Consumer>
{(value) => <div>{value}</div>}
</ThemeContext.Consumer>
)
}

export default Father

3、createContext + useContext

useContext 钩子函数接收一个 Context 对象并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。

当组件上层最近的 <MyContext.Provider> 更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext provider 的 context value 值。

import React, { useContext } from 'react'

const ThemeContext = React.createContext('light')
const Father = () => {
return (
<ThemeContext.Provider value="dark">
<Child />
</ThemeContext.Provider>
)
}

const Child = () => {
return <GrandChild />
}

const GrandChild = () => {
// 使用 useContext 引入提供的 ThemeContext
const value = useContext(ThemeContext)
return <div>{value}</div>
}

export default Father

二、Context 的原理

https://zhuanlan.zhihu.com/p/492310651?utm_id=0