React(react18)中组件通信03——简单使用 Context 深层传递参数

1. 前言

1.1 React中组件通信的其他方式

1.2 引出 Context

  • 需求场景:
    • 我们知道,如果父传子,可以通过props,如果子再传孙,还可以通过props,但是如果家族庞大,组件关系如果一颗大树,一直向下传递,这时候如果还用props,明显就显得有点费劲了。
      • 而且如果这个参数子不要孙要的情况,通过props逐层传递也不是很合理。
      • 再或者,如果这个后代离根太远了,如果还用props逐层传递下去,那么传递 props 会变的十分冗长和不便。
    • 这就需要考虑怎么能跳过中间代还能给后后代传递呢?这就需要接下来要介绍的Context了……
  • 使用 Context 可以深层传递参数,它可以在组件树不需要 props 将数据“直达”到所需的组件中,看官网介绍:
    在这里插入图片描述
    在这里插入图片描述

2. 简单例子

  • 先看实现的效果,如下是:爷爷组件给孙组件传消息:
    在这里插入图片描述
  • 代码设计——目录结构
    在这里插入图片描述
  • 代码设计——代码实现
    • context.js + App.js + index.js
      在这里插入图片描述
    • Parent.jsx + Child.jsx + GrandSon.jsx
      在这里插入图片描述

3. 语法说明

3.1 createContext(defaultValue)

  • 如下:
    在这里插入图片描述

3.2 value

  • value:该值为你想传递给所有处于这个 provider 内读取该 context 的组件,无论它们处于多深的层级。context 的值可以为任何类型。该 provider 内的组件可通过调用 useContext(SomeContext) 来获取它上面最近的 context provider 的 value

3.3 useContext(SomeContext)

  • 在组件的顶层调用 useContext 来读取和订阅 context。
    在这里插入图片描述

4. 总结

4.1 Context

4.1.1 Context 小总结

  • Context 使组件向其下方的整个树提供信息。
  • 传递 Context 的方法:
    • 通过 export const MyContext = createContext(defaultValue) 创建并导出 context。
    • 在无论层级多深的任何子组件中,把 context 传递给 useContext(MyContext) Hook 来读取它。
    • 在父组件中把 children 包在 <MyContext.Provider value={...}> 中来提供 context。
  • Context 会穿过中间的任何组件。
  • Context 可以让你写出 “较为通用” 的组件。
  • 在使用 context 之前,先试试传递 props 或者将 JSX 作为 children 传递。

4.1.2 Context 应用场景

  • 看官网介绍:
    在这里插入图片描述

4.1.3 Context-官网

4.2 createContext

  • 上下文使得组件能够无需通过显式传递参数的方式 将信息逐层传递。
  • 任何组件外调用 createContext 来创建一个或多个上下文。
    因为,通常,来自不同文件的组件都会需要读取同一个 context。因此,在一个单独的文件内定义 context 便成了常见做法。你可以使用 export 语句 将其导出,以便其他文件读取使用
  • 参考官网:
    https://zh-hans.react.dev/reference/react/createContext#createcontext.

4.3 useContext()

  • 如果 React 没有在父树中找到该特定 context 的任何 provider,useContext() 返回的 context 值将等于你在 创建 context 时指定的 默认值;
  • 注意,只有在 上层根本没有匹配的 provider 时才使用 createContext(defaultValue)调用的默认值。如果存在 <SomeContext.Provider value={undefined}> 组件在父树的某个位置,调用 useContext(SomeContext) 的组件 将会 接收到 undefined 作为 context 的值。
  • 参考官网:
    https://zh-hans.react.dev/reference/react/useContext.

5. 附代码

  • context.js

    /**
     * 1. 通常,来自不同文件的组件都会需要读取同一个 context。
     * 2. 因此,在一个单独的文件内定义 context 便成了常见做法。
     * 3. 你可以使用 export 语句 将其导出,以便其他文件读取使用
     */
    import {
          
           createContext } from "react";
    
    const MessegeContext = createContext();
    
    export default MessegeContext;
    
    
    // import { createContext } from 'react';
    
    // export const ThemeContext = createContext('light');
    // export const AuthContext = createContext(null);
    
  • Parent.jsx

    import React from "react";
    import Child from "./Child";
    import './index.css'
    import {
          
           useState } from "react";
    import MessegeContext from "./context.js";
    
    
    function Parent() {
          
          
        const [notice, setNotice] = useState('孙子,你真棒!!');
    
        return(
    
            // <div className="parent">
            //     我是父组件!
    
            //     <div className="child">
            //         <Child notice={'通知——今天放假!'}/>
            //     </div>
            // </div>
    
            // 这里的属性,只能用 value
            <MessegeContext.Provider value={
          
          notice}>
                <div className="parent">
                    我是父组件!
    
                    <div className="child">
                        <Child notice={
          
          '通知——今天放假!'}/>
                    </div>
                </div>
            </MessegeContext.Provider>
    
        )
    }
    
    export default Parent;
    
  • Child.jsx

    import React from "react";
    import GrandSon from "./GrandSon";
    import './index.css'
    
    function Child(props){
          
          
    
        return(
            <div>
                我是子组件!!!
                <br /><br />
                收到来自于父组件的数据:{
          
          props.notice}
    
                <br /><br />
                <div className="grandSon">
                    <GrandSon />
                </div>
               
            </div>
        )
    }
    
    export default Child;
    
  • GrandSon.jsx

    import {
          
           useContext } from "react"
    import MessegeContext from "./context.js";
    
    export default function GrandSon(){
          
          
    
        // 在组件的顶层调用 useContext 来读取和订阅 context。
        const msgContent = useContext(MessegeContext);
        
        console.log(msgContent);
        
        return(
            <div>
                我是孙组件!!
    
                <br />
                我收到爷爷的信息是:{
          
          msgContent}
    
            </div>
        )
    }
    
  • componenet–>index.css

    .parent{
        background-color: blueviolet;
        border: 1px solid;
        height: 900px;
        width: 600px;
        text-align: center;
    }
    
    .child{
        background-color: green;
        height: 300px;
        margin: 20px;
    }
    
    .grandSon{
        background-color: grey;
        height: 150px;
        margin: 20px;
    }
    

猜你喜欢

转载自blog.csdn.net/suixinfeixiangfei/article/details/133038359