import React, { Component, useContext, useState } from 'react';
// 解构写法 const { Provider, Consumer } = React.createContext();
// defaultValue的问题
// https://www.zhihu.com/question/310420466?sort=created
// https://stackoverflow.com/questions/49949099/react-createcontext-point-of-defaultvalue
const Context1 = React.createContext();
const Context2 = React.createContext();
function Lbox() {
const [color, setColor] = useState('red');
return (
<Context1.Provider value={{
color,
}}>
<Context2.Provider value={{
fn: () => {
setColor(color === 'red' ? 'blue' : 'red')
}
}}>
<Mbox />
</Context2.Provider>
</Context1.Provider>
)
}
function Mbox() {
return (
<>
<Sbox />
<SSbox />
<SSSbox />
</>
)
}
// 多个context
// 通过Consumer访问Provider的上下文
function Sbox() {
return (
<Context1.Consumer>
{({ color }) => (
<Context2.Consumer>
{({ fn }) => {
return (
<button style={{ color }} onClick={fn}>访问多个context</button>
)
}}
</Context2.Consumer>
)}
</Context1.Consumer>
)
}
// 只有一个context的时候这样写比较方便
// 通过class组件上的contextType访问Provider的上下文
class SSbox extends Component {
constructor(props) {
super(props);
}
render() {
return (
<SubSSbox { ...this.context }/>
)
}
}
SSbox.contextType = Context1;
class SubSSbox extends Component {
constructor(props) {
super(props);
}
render() {
const { color } = this.props;
const { fn } = this.context;
return (
<button style={{ color }} onClick={ fn }>访问单个context</button>
)
}
}
SubSSbox.contextType = Context2;
// 使用 hook api useContext
// 接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值
function SSSbox() {
const { color } = useContext(Context1);
const { fn } = useContext(Context2);
return (
<button style={{ color }} onClick={fn}>使用useContext</button>
)
}
export default Lbox;