本例只是做说明性,具体代码要运行起来,还需要加入些其他元素
主要解决的问题
在应用中可能会有很多组件会去使用到的组件,并且当使用父子传递这一机制的时候,会显得过于臃肿繁琐,所以要使用上下文的方式来进行传递。
1.创建一个context
// theme-context.js
import React from 'react'
export const ThemeContext = React.createContext('dark') // 默认为dark
2.使用context内容-class
// Demo.js
import { ThemeContext } from './theme-context'
class Demo extends React.Component {
render () {
const theme = this.context
return (<div>{theme}</div>)
}
}
Demo.contextType = ThemeContext
2.使用context内容-function
// Demo.js
import { ThemeContext } from './theme-context'
function Consumer (props) {
return (
<ThemeContext.Consumer>
{theme => (
<div>{theme}</div>
)}
</ThemeContext.Consumer>
)
}
3.传递启用
// App.js
import React from 'react'
import { ThemeContext } from './theme-context'
import Demo from 'demo'
function Wrapper (props) {
return (<Demo />)
}
class App extends React.Component {
render (
return (
<div>
<ThemeContext.Provider value="light">
<Wrapper /> // 此时 Wrapper 内的 Demo 使用的是就近的 light
</ThemeContext.Provider>
<Wrapper /> // 此时 Wrapper 内的 Demo 使用的是默认值 dark
</div>
)
)
}
在hook中使用context
父组件还是要使用<MyContext.Provider value={} />
这种方式将上下文对象全局传递出去,不同的就是使用到context的组件,可以使用function组件,来方便的接收
// Demo.js
import React from 'react'
import { ThemeContext } from './theme-context'
function Demo (props) {
const theme = React.useContext(ThemeContext)
// ... context中变化时,该组件会同步刷新
}
需要注意的问题
context会使用参考标识,也就是说,可能value不变的情况下,他会通知使用到context组件重新渲染
<Provider value={{something: 'something'}}>
<Toolbar />
</Provider>
// 此时此组件刷新的时候,他会通知组件 value发生了改变(尽管字面量并没有发生改变)
// 可以将value的值提到state中去存储
state = {
value: {something: 'something'}
}
<Provider value={this.state.value}>
<Toolbar />
</Provider>