React ‘s Context 用法

React ‘s Context 用法

此文章所提及 context 指的是新版 Context API(React 16.3 引入),在这个版本以下的 context 指的是旧时 Context API

01 What is Context API ?

一般 React 开发应用, 数据一般都是通过 props 自上而下传递。但是对于一些类似用户偏好、主题 themes 采用这种方式层层传递,随着层数的增多,会显得及其繁琐。所以 React 官方就提出了 Context API 方案,它原理是在上层容器中,暴露出上下文 context ,子组件通过 context.ConsumerClass.contextTypeuseContext 方式

接收参数。起到 传递共享 的作用

02 案例场景

不要一股脑热去使用 context ,它的使用同时也会带来一个副作用,这样会使得组件的复用性变差。

  • themes、用户偏好等,需要全局共享的数据
  • react-redux, 它其实就是使用 context 去实现 React 和 Redux 建立连接

03 Context API 用法

创建 context

context.createContext
1
2
//创建一个 Context 对象
const MyContext = React.createContext(defaultValue)

传递 context

context.Provider
1
2
// 传递 context
<MyContext.Provider value={/* 某个值 */}>

接收 context

方式:

  • useContext(函数组件)
  • Context.Consumer(通用)
  • Context.contextType(类名组件)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import React, { useContext, Component } from 'react'

const themes = {
light: {
foreground: '#000000',
background: '#eeeeee',
},
dark: {
foreground: '#ffffff',
background: '#222222',
},
}

const ThemeContext = React.createContext({
theme: themes.light,
toggleTheme: () => {},
})

export default function App() {
const [theme, setTheme] = React.useState(themes.light)

const toggleTheme = () => {
setTheme(theme === themes.dark ? themes.light : themes.dark)
}
return (
<ThemeContext.Provider
value={{
theme,
toggleTheme,
}}
>
<Toolbar />
</ThemeContext.Provider>
)
}

function Toolbar() {
return (
<div>
<ThemedButton />
</div>
)
}

// 1. useContext 接收 context 中的值(函数组件)
function ThemedButton() {
const { theme, toggleTheme } = useContext(ThemeContext)

return (
<button
style={{ background: theme.background, color: theme.foreground }}
onClick={toggleTheme}
>
toggleTheme
</button>
)
}

// 2. Context.Consumer 接收 context 中的值(通用)
function ThemedButton() {
return (
<ThemeContext.Consumer>
{({ theme, toggleTheme }) => (
<button
style={{ background: theme.background, color: theme.foreground }}
onClick={toggleTheme}
>
toggleTheme
</button>
)}
</ThemeContext.Consumer>
)
}

// 3. Context.contextType 接收 context 中的值(类名组件)
class ThemedButton extends Component {
render() {
let { theme, toggleTheme } = this.context
return (
<button
style={{ background: theme.background, color: theme.foreground }}
onClick={toggleTheme}
>
toggleTheme
</button>
)
}
}
ThemedButton.contextType = ThemeContext

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!