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

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

  • 1. 前言
    • 1.1 React中组件通信的其他方式
    • 1.2 引出 Context
  • 2. 简单例子
  • 3. 语法说明
    • 3.1 createContext(defaultValue)
    • 3.2 value
    • 3.3 useContext(SomeContext)
  • 4. 总结
    • 4.1 Context
      • 4.1.1 Context 小总结
      • 4.1.2 Context 应用场景
      • 4.1.3 Context-官网
    • 4.2 createContext
    • 4.3 useContext()
  • 5. 附代码

1. 前言

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

  • React(react18)中组件通信01——props.
  • React(react18)中组件通信02——消息订阅与发布、取消订阅以及卸载组件时取消订阅.

1.2 引出 Context

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

2. 简单例子

  • 先看实现的效果,如下是:爷爷组件给孙组件传消息:
    React(react18)中组件通信03——简单使用 Context 深层传递参数_第3张图片
  • 代码设计——目录结构
    React(react18)中组件通信03——简单使用 Context 深层传递参数_第4张图片
  • 代码设计——代码实现
    • context.js + App.js + index.js
      React(react18)中组件通信03——简单使用 Context 深层传递参数_第5张图片
    • Parent.jsx + Child.jsx + GrandSon.jsx
      React(react18)中组件通信03——简单使用 Context 深层传递参数_第6张图片

3. 语法说明

3.1 createContext(defaultValue)

  • 如下:
    React(react18)中组件通信03——简单使用 Context 深层传递参数_第7张图片

3.2 value

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

3.3 useContext(SomeContext)

  • 在组件的顶层调用 useContext 来读取和订阅 context。
    React(react18)中组件通信03——简单使用 Context 深层传递参数_第8张图片

4. 总结

4.1 Context

4.1.1 Context 小总结

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

4.1.2 Context 应用场景

  • 看官网介绍:
    React(react18)中组件通信03——简单使用 Context 深层传递参数_第9张图片

4.1.3 Context-官网

  • 如下:
    https://zh-hans.react.dev/learn/passing-data-deeply-with-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)调用的默认值。如果存在 组件在父树的某个位置,调用 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(
    
            // 
    // 我是父组件! //
    // //
    //
    // 这里的属性,只能用 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;
    }
    

你可能感兴趣的:(react,react.js,前端,前端框架,react组件通信,createContext,useContext)