0x000 概述
Context
就是全局state
啦~~
0x001 问题
先上栗子,我们需要在Topbar
中用到theme
,但是theme
必须从最外层传入,所以必须从最外层传入App
,再传入TopBar
,这只传递了两次,但是如果全部组件都需要theme
呢?或者有一个非常深的组件需要theme
,而中间的大部分组件都不需要theme
呢?为了传递这个theme
必须一层一层的传递下去,有点难受。
class TopBar extends React.Component {
redder() {
return <div>
{this.props.theme}
</div>
}
}
class App extends React.Component {
render() {
return <div>
<TopBar theme={this.props.theme}/>
</div>
}
}
ReactDom.render(
<App theme='dark'/>,
document.getElementById('app')
)
0x002 解决
Context
可以解决这个问题,上栗子:
-
创建
context
const ThemeContext = React.createContext('theme');
React.createContext
创建了一个context
,它返回一个对象,可以打印出来:
需要注意的是:-
Consumer
:消费者 -
Provider
:提供者
-
-
创建提供者
class App extends React.Component { constructor(props) { super(props); this.state = { theme: 'dark' } } render() { return ( <ThemeContext.Provider value={this.state.theme}> <ThemedButton/> <button onClick={() => this.handleChangeTheme()} className='btn btn-primary'> 修改主题</button> </ThemeContext.Provider> ); } handleChangeTheme() { this.setState({ theme: this.state.theme === 'light' ? 'dark' : 'light' }) } }
ThemeContext.Provider
是一个组件,value
属性提供的值在所有的Consumer
中都可以访问到,前提是必须包裹在Provider
中。 -
创建消费者
class ThemedButton extends React.Component { render() { return <ThemeContext.Consumer> { (value) => <div>{value}</div> } </ThemeContext.Consumer> } }
ThemeContext.consumer
是一个组件,包裹在其中的函数组件可以访问到ThemeContext.Provider
声明时候传入的value
,并且在ThemeContext.Provider
的value
变动的时候,再次渲染。 -
使用
ReactDom.render( <App theme='dark'/>, document.getElementById('app') )
- 效果
-
整个栗子:
import ReactDom from 'react-dom' import React from 'react' const ThemeContext = React.createContext('theme'); class ThemedButton extends React.Component { render() { return <ThemeContext.Consumer> { (value) => <div>{value}</div> } </ThemeContext.Consumer> } } class App extends React.Component { constructor(props) { super(props); this.state = { theme: 'dark' } } render() { return ( <ThemeContext.Provider value={this.state.theme}> <ThemedButton/> <button onClick={() => this.handleChangeTheme()} className='btn btn-primary'> 修改主题</button> </ThemeContext.Provider> ); } handleChangeTheme() { this.setState({ theme: this.state.theme === 'light' ? 'dark' : 'light' }) } } ReactDom.render( <App theme='dark'/>, document.getElementById('app') )
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。