1、介绍
之前文章介绍了使用Props进行参数和函数引用的传参达到组件通信的效果。这次使用context来实现这个效果。
2、创建组件
创建 Grandpa、Father、Son1、Son2、Son3 组件
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
| const Grandpa = () => { return ( <> <div>我是 Grandpa</div> <Father /> </> ) }
const Father = () => { return ( <> <div>我是 Father</div> <Son1 /> <Son2 /> </> ) }
const Son1 = () => { return ( <> <div>我是Son1</div> </> ) }
class Son2 extends React.Component { render(){ return <div>我是 Son2</div> } }
const Son3 = () => { return ( <> <div>我是 Son3</div> </> ) }
function App() { return ( <div className="App"> <Grandpa /> </div> ) }
|
3、创建 context 对象
引入 createContext 函数,用于构造context对象
1 2
| import { createContext } from 'react' const context = createContext()
|
从 context 中结构出 Provider、Consumer 两个组件
1
| const { Provider, Consumer } = context
|
4、注入数据
在 App 中使用 Provider 组件进行注入,并把对应数据和方法传递下去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function App() { const [name, setName] = useState('梁又文') const data = { name, age: '20', setName, } return ( <Provider value={data}> <div className="App"> <Grandpa /> </div> </Provider> ) }
|
5、子孙组件获取数据
5.1 函数组件
通过 Consumer 获取数据
Son1
1 2 3 4 5 6 7 8 9 10 11
| const Son1 = () => { return ( <Consumer> {({ name, setName }) => ( <div> 我是Son1,我拿到的数据是:{name} <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button> </div> )} </Consumer> ) }
|
5.2 类组件
通过 contextType 挂载 context 的属性
Son2
1 2 3 4 5 6 7 8 9 10 11
| class Son2 extends Component { static contextType = context render() { const { name, setName } = this.context return ( <> 我是Son2,我拿到的数据是:{name} <button onClick={() => setName('我是被Son2修改的名字')}>修改名字</button> </> ) } }
|
5.3 useContext 方式
通过把 context 对象传入到 useContext 中,返回所有数据。
1 2 3 4 5 6 7 8 9
| const Son3 = () => { const { name, setName, age } = useContext(context) return ( <div> 我是Son1,Grandpa今年{age}岁了。我拿到的数据是:{name} <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button> </div> ) }
|
6、最终代码
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
| import { Component, createContext, useState, useContext } from 'react' const context = createContext() const { Provider, Consumer } = context export { Consumer, context }
const Grandpa = () => { return ( <> <div>我是 Grandpa</div> <Father /> </> ) }
const Father = () => { return ( <> <div>我是 Father</div> <Son1 /> <Son2 /> <Son3 /> </> ) }
const Son1 = () => { return ( <Consumer> {({ name, setName }) => ( <div> 我是Son1,我拿到的数据是:{name} <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button> </div> )} </Consumer> ) }
class Son2 extends Component { static contextType = context render() { const { name, setName } = this.context return ( <> 我是Son2,我拿到的数据是:{name} <button onClick={() => setName('我是被Son2修改的名字')}>修改名字</button> </> ) } }
const Son3 = () => { const { name, setName, age } = useContext(context) return ( <div> 我是Son1,Grandpa今年{age}岁了。我拿到的数据是:{name} <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button> </div> ) }
function App() { const [name, setName] = useState('梁又文') const data = { name, age: '20', setName, } return ( <Provider value={data}> <div className="App"> <Grandpa /> </div> </Provider> ) }
export default App
|