React context usage

Context provides a way to pass data between component trees without manually adding props for each layer of components.

1. Usage

React.createContext

const MyContext = React.createContext(defaultValue);

Create a Context object. When React renders a component subscribed to this Context object, the component will read the current context value from the matching Provider closest to itself in the component tree.

Only when there is no matching Provider in the tree where the component is located, its defaultValue parameter will take effect. This helps in testing components without using a Provider to wrap the component. Note: When undefined is passed to the Provider's value, the defaultValue of the consuming component will not take effect.

Context.Provider

<MyContext.Provider value={/* 某个值 */}>

Each Context object returns a Provider React component, which allows consuming components to subscribe to context changes.

Provider receives a value attribute and passes it to the consuming component. A Provider can have a corresponding relationship with multiple consumer components. Multiple Providers can also be used nested, and the inner layer will overwrite the outer layer's data.

Context.Consumer

<MyContext.Consumer>
  {value => /* 基于 context 值进行渲染*/}
</MyContext.Consumer>

Here, React components can also subscribe to context changes. This allows you to subscribe to the context in functional components.

2. Example application

As shown in the figure, two variables are defined in the parent component: fruit and count. The child component can get the fruit of the parent component, and the child component can get the fruit of the parent component, and can change the value of count.

The implementation steps are as follows:

2.1 Create a new file context.js

Create a Context object and export the Provider and Consumer containers.

import { createContext } from 'react'

export const { Provider, Consumer } = createContext()

2.2 Create a new parent component index.js

import React, { Component } from 'react'
import { Provider } from './context' // 引入Provider
import Son from './Son' // 引入子组件

class Main extends Component {
  constructor(props) {
    super(props)
    this.state = {
      fruit: 'apple',
      count: 0,
    }
  }

  componentDidMount() {}

  getContext = () => {
    const { fruit, count } = this.state
    return {
      fruit,
      countUtil: {
        addCount: num => {
          this.setState({
            count: count + num,
          })
        },
        delCount: num => {
          this.setState({
            count: count - num,
          })
        },
      },
    }
  }

  render() {
    const { fruit, count } = this.state
    return (
      // Provider 容器, 其value接收一个getContext方法
      <Provider value={this.getContext()}>
        父组件 fruit = {fruit}, count = {count}
        <hr />
        <Son />
      </Provider>
    )
  }
}

export default Main

2.3 Create a new sub-component Son.js

import React, { Component } from 'react'
import { Consumer } from './context' // 引入Consumer
import GrandSon from './GrandSon' // 引入子子组件

class Main extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  render() {
    return (
      // Consumer 容器,可以拿到父组件传递下来的 fruit 属性, 并可以展示对应的值
      <Consumer>
        {context => (
          <div>
            子组件 fruit={context.fruit}
            <hr />
            <GrandSon />
          </div>
        )}
      </Consumer>
    )
  }
}

export default Main

2.4 Create a new sub-component GrandSon.js

import React, { Component } from 'react'
import { Consumer } from './context' // 引入Consumer

class Main extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  render() {
    return (
      // Consumer 容器,可以拿到父组件传递下来的 fruit 属性, 以及 countUtil对象下的 addCount 和 delCount 方法
      <Consumer>
        {context => (
          <div>
            子子组件 fruit={context.fruit}
            <br />
            <button type="button" onClick={() => context.countUtil.addCount(2)}>
              加2
            </button>
            &nbsp;
            <button type="button" onClick={() => context.countUtil.delCount(3)}>
              减3
            </button>
            <hr />
          </div>
        )}
      </Consumer>
    )
  }
}

export default Main

 

Guess you like

Origin blog.csdn.net/m0_62336865/article/details/130266412