1、介绍

之前文章介绍了使用Props进行参数和函数引用的传参达到组件通信的效果。这次使用context来实现这个效果。

2、创建组件

创建 GrandpaFatherSon1Son2Son3 组件

  1. const Grandpa = () => {
  2. return (
  3. <>
  4. <div>我是 Grandpa</div>
  5. <Father />
  6. </>
  7. )
  8. }
  9. const Father = () => {
  10. return (
  11. <>
  12. <div>我是 Father</div>
  13. <Son1 />
  14. <Son2 />
  15. </>
  16. )
  17. }
  18. const Son1 = () => {
  19. return (
  20. <>
  21. <div>我是Son1</div>
  22. </>
  23. )
  24. }
  25. class Son2 extends React.Component {
  26. render(){
  27. return <div>我是 Son2</div>
  28. }
  29. }
  30. const Son3 = () => {
  31. return (
  32. <>
  33. <div>我是 Son3</div>
  34. </>
  35. )
  36. }
  37. function App() {
  38. return (
  39. <div className="App">
  40. <Grandpa />
  41. </div>
  42. )
  43. }

3、创建 context 对象

引入 createContext 函数,用于构造context对象

  1. import { createContext } from 'react'
  2. const context = createContext()

context 中结构出 ProviderConsumer 两个组件

  1. const { Provider, Consumer } = context

4、注入数据

在 App 中使用 Provider 组件进行注入,并把对应数据和方法传递下去

  1. function App() {
  2. const [name, setName] = useState('梁又文')
  3. const data = {
  4. name,
  5. age: '20',
  6. setName,
  7. }
  8. return (
  9. <Provider value={data}>
  10. <div className="App">
  11. <Grandpa />
  12. </div>
  13. </Provider>
  14. )
  15. }

5、子孙组件获取数据

5.1 函数组件

通过 Consumer 获取数据

Son1

  1. const Son1 = () => {
  2. return (
  3. <Consumer>
  4. {({ name, setName }) => (
  5. <div>
  6. 我是Son1,我拿到的数据是:{name} <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button>
  7. </div>
  8. )}
  9. </Consumer>
  10. )
  11. }

5.2 类组件

通过 contextType 挂载 context 的属性

Son2

  1. class Son2 extends Component {
  2. static contextType = context
  3. render() {
  4. const { name, setName } = this.context
  5. return (
  6. <>
  7. 我是Son2,我拿到的数据是:{name} <button onClick={() => setName('我是被Son2修改的名字')}>修改名字</button>
  8. </>
  9. )
  10. }
  11. }

5.3 useContext 方式

通过把 context 对象传入到 useContext 中,返回所有数据。

  1. const Son3 = () => {
  2. const { name, setName, age } = useContext(context)
  3. return (
  4. <div>
  5. 我是Son1Grandpa今年{age}岁了。我拿到的数据是:{name}
  6. <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button>
  7. </div>
  8. )
  9. }

6、最终代码

  1. import { Component, createContext, useState, useContext } from 'react'
  2. const context = createContext()
  3. const { Provider, Consumer } = context
  4. export { Consumer, context }
  5. const Grandpa = () => {
  6. return (
  7. <>
  8. <div>我是 Grandpa</div>
  9. <Father />
  10. </>
  11. )
  12. }
  13. const Father = () => {
  14. return (
  15. <>
  16. <div>我是 Father</div>
  17. <Son1 />
  18. <Son2 />
  19. <Son3 />
  20. </>
  21. )
  22. }
  23. const Son1 = () => {
  24. return (
  25. <Consumer>
  26. {({ name, setName }) => (
  27. <div>
  28. 我是Son1,我拿到的数据是:{name} <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button>
  29. </div>
  30. )}
  31. </Consumer>
  32. )
  33. }
  34. class Son2 extends Component {
  35. static contextType = context
  36. render() {
  37. const { name, setName } = this.context
  38. return (
  39. <>
  40. 我是Son2,我拿到的数据是:{name} <button onClick={() => setName('我是被Son2修改的名字')}>修改名字</button>
  41. </>
  42. )
  43. }
  44. }
  45. const Son3 = () => {
  46. const { name, setName, age } = useContext(context)
  47. return (
  48. <div>
  49. 我是Son1Grandpa今年{age}岁了。我拿到的数据是:{name}
  50. <button onClick={() => setName('我是被Son1修改的名字')}>修改名字</button>
  51. </div>
  52. )
  53. }
  54. function App() {
  55. const [name, setName] = useState('梁又文')
  56. const data = {
  57. name,
  58. age: '20',
  59. setName,
  60. }
  61. return (
  62. <Provider value={data}>
  63. <div className="App">
  64. <Grandpa />
  65. </div>
  66. </Provider>
  67. )
  68. }
  69. export default App