React uses the Context method to implement component communication (case description nested value transfer + detailed usage summary)

foreword

In the previous article, we introduced the use of props in react to achieve component communication, such as father-son, grandparent communication, but it is still very troublesome to use props to pass layer by layer, so today's article will introduce a new usage - using Context realizes the formation of communication

Context

This is explained in the official react documentation: Context provides a way to transfer data between component trees without manually adding props to each layer of components. The portal attached here Context-react
Context is designed to share data that is "global" to a component tree, such as the currently authenticated user, theme or preferred language. Let's take a look at how to use Context to achieve component communication

grandchildren's value

Outermost component (ancestor component):

  1. Introduce the parent component (hello.js) and introduce the MainContext in the context
  2. Use <MainContext.Provider value={this.state.arr}> to provide services to pass values, value is the value to be passed
import React, {
    
     Component } from 'react'
import Hello from './hello'
import MainContext from './context'

export class Main extends Component {
    
    
    state = {
    
    
        // arr: [1, 2, 3],
        arr: 'hello',
        obj: {
    
    name: 'chaochao'}
    }
  render() {
    
    
    return (
      <div>
          <MainContext.Provider value={
    
    this.state.arr}>
                Main Page
                <Hello/>
          </MainContext.Provider>
      </div>
    )
  }
}

export default Main

Grandson component:
The ancestor component above has already used MainContext.Provider to pass values, so there is no need to pass values ​​layer by layer here. In the grandchild component, you can directly use the MainContext.Consumer component to receive
1. Introduce MainContext from context.js
2. Use MainContext.Consumer to get the value
so that you can successfully get the value of the ancestor component in the grandchild component

import React, {
    
     Component } from 'react'
import MainContext from './context'

export class World extends Component {
    
    
  render() {
    
    
    return (
        <MainContext.Consumer>
        	{
    
    
				context => {
    
    
					return (
						<div>World Page --- {
    
    context}</div
					)
				}
			}
        </MainContext.Consumer>
    )
  }
}

export default World

In addition to using MainContext.Consumer to get the value, there is another way:
you can use static contextType = MainContext or Hello.contextType = MainContext, so that you can directly use this.context to get the incoming value

export class Hello extends Component {
    
    
    // static contextType = MainContext
    render() {
    
    
        return (
            <div>Hello Page==={
    
    this.context}
                <World />
            </div>
        )
    }
}

Hello.contextType = MainContext // 等同于第二行代码的作用

nested pass-by-value

The above example is that the ancestor component passes the value to the grandchild component group. The grandchild component uses MainContext.Consumer to receive the value, but if the grandchild component also receives the value passed by other components, then we need to nest MainContext.Consumer to receive the value.
Here's an example:
create a new userContext.js:

import React from 'react'
const UserContext = React.createContext()
export default UserContext

Nested pass-by-value in ancestor components:

  1. Introduce two context files at the same time
  2. Pay attention to see MainContext.Provider and UserContext.Provider for nested value transfer
import React, {
    
     Component } from 'react'
import Hello from './hello'
import MainContext from './context'
import UserContext from './userContext'

export class Main extends Component {
    
    
    state = {
    
    
        // arr: [1, 2, 3],
        arr: 'hello',
        obj: {
    
    name: 'chaochao'}
    }
  render() {
    
    
    return (
      <div>
          <MainContext.Provider value={
    
    this.state.arr}>
              <UserContext.Provider value={
    
    this.state.obj}>
                Main Page
                <Hello/>
              </UserContext.Provider>
          </MainContext.Provider>
      </div>
    )
  }
}

export default Main

In the grandson component:
1. It is also necessary to introduce two contexts at the same time
. 2. The received values ​​also need to be nested. Pay attention to the writing method
so that you can receive two different values.

import React, {
    
     Component } from 'react'
import MainContext from './context'
import UserContext from './userContext'

export class World extends Component {
    
    
  render() {
    
    
    return (
        // 函数式组件中比较推荐使用Consumer进行取值消费
        <MainContext.Consumer>
            {
    
    context => {
    
    
                return <UserContext.Consumer>
                    {
    
    user => {
    
    
                        console.log(context, user)
                        return (
                            <div>World Page --- {
    
    context} --- {
    
    user.name}</div>
                        )
                    }}
                </UserContext.Consumer>
            }}
        </MainContext.Consumer>
    )
  }
}

export default World

Context usage steps summary

As before, the usage is realized through a small case. The ancestor component passes the value to the grandchild component and creates a
new context.js file to use
the content in the context context.js:

import React from 'react'
// 创建一个 Context 对象,组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。
const MainContext = React.createContext('这里面可以设置默认值')

export default MainContext
// 传值使用Provider接收value属性,传递给消费组件
<MainContext.Provider value={
    
    /* 某个值 */}>

Two ways to receive a value:

  1. Use Context.Consumer (mostly for functional components)
<MainContext.Consumer>
  {
    
    value => /* 基于 context 值进行渲染*/}
</MainContext.Consumer>
  1. Use Class.contextType to mount on the class, and then use this.context to consume the value on the most recent Context. It can be accessed in any lifecycle, including the render function. (mostly used for class components)
static contextType = MainContext
// 或者
Hello.contextType = MainContext 
// 就可以直接用this.context访问了

This article ends here. If it is helpful to you, please like, follow and support. Thank you~ I
will continue to bring you high-quality front-end content in the future~ Keep updating! ! !

Guess you like

Origin blog.csdn.net/weixin_45745641/article/details/123489191