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;