【React】React18 Hooks 之 useContext

目录

  • useContext
    • 1、Provider和 useContext
    • 2、Provider 和Consumer
    • 3、Provider 嵌套
    • 4、React.createContext提供的Provider和class的contextType属性
    • 5、读、写Context
      • (1)父组件修改Context
      • (2)子组件修改Context
  • 好书推荐

在这里插入图片描述

useContext官方地址
使用 Context 深度传递数据

通常,您会通过 props 将信息从父组件传递到子组件。但是,如果您必须通过中间的许多组件传递信息,或者应用中的许多组件都需要相同的信息,则传递 props 会变得冗长且不方便。Context允许父组件向其下方树中的任何组件(无论深度如何)提供一些信息,而无需通过 props 明确传递

简单来说使用Context可以实现跨组件层级传递数据,不用层层传递数据。本文介绍三种Context的使用方式。

  • 函数组件:React.createContext提供的ProvideruseContext钩子
  • React.createContext提供的ProviderConsumer
  • Provider嵌套
  • Class组件:React.createContext提供的ProviderclasscontextType属性
  • 读、写Context

useContext

useContext是一个 React Hook,可让您从组件读取和订阅上下文。

用法:

const value = useContext(SomeContext)

参数的含义:
SomeContext:使用createContext创建的上下文。上下文本身并不包含信息,它只代表您可以提供或从组件中读取的信息类型。
返回值的含义:
value:useContext返回调用组件的上下文值,传递给最接近的SomeContext的值

1、Provider和 useContext

新建个context.js,导出createContext()的返回值

import { createContext } from "react";
export default createContext();

App.js,导入上面写的context,并使用context提供的Provider组件进行包裹,圈定局部的全局作用域,传值后可以提供给子组件进行消费。当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。

import Context from "./context";
import Test from "./Test"
function App() {const value = "app 中的数据"return (<><Context.Provider value={value}><div className="Appy" ><Test /></div></Context.Provider></>);
}export default App;

新建个Test.js,

import Context from "./context"
import MyComponent from "./MyComponent"
const Test1 = () => {return <><MyComponent/><div></div></>
}
export default Test1

新建个MyComponent.js,使用useContext钩子接收Context提供的参数

import Context from "./context"
import { useContext } from "react"
const MyComponent = ()=>{const value = useContext(Context)return <><div>value:{value}</div></>
}
export default MyComponent

可以看到页面中显示如下:
在这里插入图片描述
使用Components分析如下:

在这里插入图片描述

2、Provider 和Consumer

上面的MyComponent.js 文件,我们可以使用Context.Consumer组件接收数据。在MyComponent组件中,导入context,使用其提供的Consumer组件来订阅Context的变更,需要一个函数作为子元素,函数的第一个形参便是Provider组件提供的value值。如下:

import Context from "./context"
import { useContext } from "react"
const MyComponent = ()=>{const value = useContext(Context)return <><Context.Consumer>{value=><div>value1:{value}</div>}</Context.Consumer></>
}
export default MyComponent

3、Provider 嵌套

新建context.js,创建ThemeContext,AuthContext,然后再分别创建创建 ThemeContext 、AuthContext 的 Provider 组件,Provider 组件主要提供方法。


// context.js
import React, { createContext, useState, useContext } from 'react';// 创建 ThemeContext
const ThemeContext = createContext();// 创建 ThemeContext 的 Provider 组件
const ThemeProvider = ({ children }) => {const [theme, setTheme] = useState('light'); // 假设初始主题是 'light'// 可以通过函数来切换主题const toggleTheme = () => {setTheme(theme === 'light' ? 'dark' : 'light');};return (<ThemeContext.Provider value={{ theme, toggleTheme }}>{children}</ThemeContext.Provider>);
};// 创建 AuthContext
const AuthContext = createContext();// 创建 AuthContext 的 Provider 组件
const AuthProvider = ({ children }) => {const [user, setUser] = useState(null); // 假设初始用户是 null// 可以通过函数来设置用户const login = (userData) => {setUser(userData);};const logout = () => {setUser(null);};return (<AuthContext.Provider value={{ user, login, logout }}>{children}</AuthContext.Provider>);
};// 导出 ThemeProvider 和 AuthProvider,以及它们各自的 Context
export { ThemeContext, ThemeProvider, AuthContext, AuthProvider };

App.js,导入ThemeProvider, AuthProvider,层层嵌套。

import React from 'react';
import { ThemeProvider, AuthProvider } from './context.js'; // 导入提供者
import MyComponent from './MyComponent'; // 假设您有一个 MyComponent 组件const App = () => {return (<ThemeProvider ><AuthProvider ><MyComponent /> {/* MyComponent 现在可以访问 ThemeContext 和 AuthContext */}</AuthProvider></ThemeProvider>);
};export default App;

MyComponent.js,导入ThemeContext, AuthContext ,使用useContext获取ThemeContext, AuthContext 的Provider组件传递的参数。

import React, { useContext } from 'react';
import { ThemeContext, AuthContext } from './context.js'; // 导入 Contextconst MyComponent = () => {console.log(useContext(ThemeContext),'useContext(ThemeContext)')const { theme, toggleTheme } = useContext(ThemeContext);const { user, login, logout } = useContext(AuthContext);console.log(useContext(AuthContext),'useContext(ThemeContext)')// 使用 theme、toggleTheme、user、login 和 logout 做一些事情...return (// ... 组件的 JSX<div><p>当前主题: {theme}</p><button onClick={toggleTheme}>切换主题</button>{user ? (<div><p>已登录用户: {user.name}</p><button onClick={logout}>登出</button></div>) : (<button onClick={() => login({ name: 'John Doe' })}>登录</button>)}</div>);
};export default MyComponent;

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

4、React.createContext提供的Provider和class的contextType属性

static contextType 是一种在类组件中直接访问 Context 值的方式,而不必明确地传递一个 <Context.Consumer> 组件。static contextType 应该被定义在类组件的外部,而不是在 render 方法内部或组件的类体内部。

挂载在 class 上的 contextType 属性会被重赋值为一个由React.createContext() 创建的 Context 对象。这能让你使用 this.context 来消费最近 Context 上的那个值。你可以在任何生命周期中访问到它,包括 render 函数中。
使用static关键字添加静态属性,和直接在class添加属性效果一致,最终都会添加到类上,而不是类的实例上

import React, { Component } from "react";
import context from "./context";
class Test1 extends Component {static contextType = context;render() {console.log(Test1.contextType,'contextType');console.log(this.context,'context');const value = this.context;return <div>第三种使用Context方式获取的值:{JSON.stringify(value)}</div>;}
}// Test1.contextType = context; //此处与写static关键字作用一致
export default Test1;

可以看到打印的Test1.contextTypeReact.createContext() 创建的 Context 对象,打印this.context为最近的 Context 上的值
在这里插入图片描述

5、读、写Context

(1)父组件修改Context

App.js中,更改Context数据,调用组件中的onChange方法。Provider的value不再传入一个简单结构的对象,而是将useState的返回值作为新对象的key/value,子组件便能调用App的setStore函数进行更新

import Context from "./context";
import Test from "./Test1" 
import { useState } from "react"
function App() {const value = "app 中的数据"const [store, setStore] = useState(value);const onChange = ()=>{setStore("app 数据 change")}return (<><Context.Provider value={{store, setStore}}><div className="Appy" ><Test /><button onClick={onChange}>按钮</button></div></Context.Provider></>);
}export default App;

Test.js中,使用useContext接收Context数据。点击父组件中的按钮,数据从 app 中的数据变为app 数据 change

import Context from "./context"
import { useContext } from "react"
const Test1 = () => {const value = useContext(Context)console.log(value,'test1组件接收到的')return <>{value.store}<div></div></>
}
export default Test1

(2)子组件修改Context

这里更改子组件的代码,新增一个button按钮,使用context接收过来的setStore函数,修改Context数据。点击button之后,数据由app 中的数据变为子组件修改Context成功。效果与在父组件中修改Context数据一样。

import Context from "./context"
import { useContext } from "react"
// import MyComponent from "./MyComponent"
const Test1 = () => {const context = useContext(Context)return <>{value.store}<button onClick={()=>context.setStore("子组件修改Context成功")}>子组件button</button></>
}
export default Test1

好书推荐

《Rust Web开发》

如果你厌倦了缓慢、占用大量资源且不稳定的模板化Web开发工具,Rust就是你的解决方案。Rust服务提供了稳定的安全保证、非凡的开发经验,以及能够自动防止常见错误的编译器。

《Rust Web开发》教你使用Rust以及重要的Rust库(如异步运行时的Tokio、用于Web服务器和API的Warp,以及运行外部HTTP请求的Reqwest)来创建服务端的Web应用。《Rust Web开发》包含大量的代码示例以及专业的提示,以帮助你创建项目和组织代码。随着学习的深入,你将创建一个完整的Q&A Web服务并逐章迭代你的代码,就像参与了真实的项目开发一样。

这不是一本参考书,而是一本工作手册。正在构建的应用程序在设计上做出了一些妥协,以便在适当的时候解释概念。需要阅读整本书的内容才能最终将应用程序部署到生产环境中。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/43578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NPDP有什么价值?究竟值不值得去考?

NPDP其实就是产品经理国际资格认证&#xff0c;是美国产品开发管理协会发起的&#xff0c;集理论、方法和实践一体&#xff0c;在新产品开发方面有一个很全面的知识体系。是国际公认的新产品开发专业认证&#xff0c;具有权威性。 NPDP能够很好地帮你在做新产品的道路上少走弯…

【已解决】腾讯云安装了redis,但是本地访问不到,连接不上

汇总了我踩过的所有问题。 查看配置文件redis.conf 1、把bind 127.0.0.1给注释掉&#xff08;前面加个#就是&#xff09;或者改成bind 0.0.0.0&#xff0c;因为刚下载时它是默认只让本地访问。&#xff08;linux查找文档里的内容可以输入/后面加需要匹配的内容&#xff0c;然后…

clickhouse-jdbc-bridge rce

clickhouse-jdbc-bridge 是什么 JDBC bridge for ClickHouse. It acts as a stateless proxy passing queries from ClickHouse to external datasources. With this extension, you can run distributed query on ClickHouse across multiple datasources in real time, whic…

Java基础-组件及事件处理(上)

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 Swing 概述 MVC 架构 Swing 特点 控件 SWING UI 元素 JFrame SWING 容器 说明 常用方法 示例&a…

服务器信息获取工具

功能介绍 SSH连接到远程服务器&#xff1a; 用户可以输入目标服务器的IP地址、用户名、密码以及SSH端口&#xff08;默认22&#xff09;。 工具会尝试连接到远程服务器&#xff0c;并在连接失败时显示错误信息。 运行命令并返回输出&#xff1a; 工具可以在远程服务器上运…

python (必看)10个提升接口自动化编写效率的脚本!

亲爱的开发者们&#xff0c;&#x1f44b; 在快速迭代的软件开发周期中&#xff0c;接口自动化测试扮演着至关重要的角色。今天&#xff0c;我们将分享10个实用的Python小脚本&#xff0c;它们能够显著提升你编写接口自动化测试的效率。无论是初学者还是资深工程师&#xff0c;…

算法体系-26 第二十六节:第26节:单调栈结构 (5节)

一 单调栈知识讲解 1.1描述 一个数组里面想的到每个位置与他最近的左边和右边比他小的最近的信息 1.2 分析 通过单调栈的特点&#xff0c;for遍历数组中的每个数&#xff0c;当前数来的时候对比单调栈中的数进行每个数的左右判断完满足条件的进行更新到当前i种的 int[][] re…

采用3种稀疏降噪模型对心电信号进行降噪(Matlab R2021B)

心电信号采集自病人体表&#xff0c;是一种无创性的检测手段。因此&#xff0c;心电信号采集过程中&#xff0c;本身也已经包含了机体内部其他生命活动带来的噪声。同时&#xff0c;由于采集设备和环境中存在电流的变化&#xff0c;产生电磁发射等物理现象&#xff0c;会对心电…

学习测试7-ADB的使用

ADB是什么&#xff1f; ADB&#xff0c;即 Android Debug Bridge&#xff08;安卓调试桥&#xff09; 是一种允许模拟器或已连接的 Android 设备进行通信的命令行工具&#xff0c;它可为各种设备操作提供便利&#xff0c;如安装和调试应用&#xff0c;并提供对 Unix shell&…

最新全国1-5级标准河流水系矢量数据

2023最新全国一级&#xff5e;五级标准河流水系 shp 矢量数据 2023最新全国一级&#xff5e;五级标准河流水系 shp 矢量数据 Arcgis 五级河流水系全国合集和按省区分 坐标系&#xff1a;wgs84 更新年份&#xff1a;2023年 包含20230SM提取全国超详细水体 Arcgis 矢量数据&a…

TIA博途与威纶通触摸屏无实物仿真调试的具体方法示例

TIA博途与威纶通触摸屏无实物仿真调试的具体方法示例 准备条件: TIA PORTAL V16 S7-PLCSIM V16 EasyBuilderPro V6.9.1 NetToPLCsim V1.2.5 如有需要,可以在这个链接中下载 NetToPLCSim - Browse Files at SourceForge.net538 weekly downloads3 weekly downloads12 weekly d…

R包:蛋白质组学质控评估PTXQC包

介绍 PTXQC包是2016年发表在J Proteome Res期刊上的R包&#xff0c;它主要是对MaxQuant输出结果进行提取处理从而获得评估蛋白质质量结果。 安装 从github安装&#xff0c;安装过程会自动构建tutorial。 devtools::install_github("cbielow/PTXQC", build_vignet…

AI数字人直播saas系统源码部署火爆!无人直播系统全攻略

随着直播行业的日益兴盛&#xff0c;各种直播模式和玩法不断涌现。其中&#xff0c;AI数字人直播更是凭借着其在降本增效的独特优势而在众多直播模式中脱颖而出&#xff0c;成为了众多企业已经引进或计划引进的新型技术。而各大数字人源码厂商推出的AI数字人直播saas系统源码部…

走拼箱货必看海运拼箱的实用技巧

在国际海运运输中&#xff0c;海运拼箱适用于货物数量较少或体积不足以填满整个集装箱的情况。 海运拼箱货物通常由物流公司或货代进行组织和管理。多个货主的货物通过合理拼装&#xff0c;使集装箱空间得到充分利用。 那么&#xff0c;在海运拼箱和整柜有哪些不同&#xff0c…

Linux -- 认识gcc/g++、代码的编译过程

目录 前言&#xff1a; 使用 gcc/g&#xff1a; 代码的编译过程&#xff1a; 预处理&#xff1a; 头文件展开&#xff1a; 宏替换去注释&#xff1a; ​编辑 条件编译&#xff1a; 编译&#xff1a; 汇编&#xff1a; 链接&#xff1a; 动态库&#xff08;动态链…

使用Simulink基于模型设计(二):系统定义和布局

Simulink模型的顶层系统布局是许多工程团队可以使用的公共环境&#xff0c;是基于模型的设计范式&#xff1a;分析、设计、检验和实现。您可以通过确定模型的结构和各个组件来定义顶层系统。然后&#xff0c;您可以将模型按照层次结构进行组织&#xff0c;分别与系统的各个组件…

【鸿蒙学习笔记】交互事件

官方文档&#xff1a;交互事件 目录标题 分类交互事件-触屏交互事件-手势事件单一手势 分类 交互事件-触屏 在组件上按下(Down) , 滑动(Move) , 抬起(up)时触发的回调事件。包括点击事件、触摸事件和拖拽事件 交互事件-手势事件 在手机上点击打开应用 , 长按后拖动应用 , 这…

自动化数据集成的BI工具,为你提供决策洞察力

传统的商业智能&#xff08;BI&#xff09;报表系统采用的是“业务提报表需求&#xff0c;IT进行开发”的模式。决策管理者和业务人员提出用报表等来展示经营管理数据的需求&#xff1b;接着IT响应需求&#xff0c;进行需求沟通、数据处理加工、报表开发等主体工作&#xff1b;…

RFID资产管理系统 RFID固定资产管理系统

大多数企业都曾被固定资产管理“难”的问题困扰&#xff1a;账物不符、查询不便、盘点耗时……因此&#xff0c;越来越多的企业选择用资产管理系统&#xff0c;来实现资产智能化管理。 RFID资产管理系统方案是针对大多数企业存在的资产管理痛点&#xff0c;采用RFID技术&#…

uni-app三部曲之三: 路由拦截

1.引言 路由拦截&#xff0c;个人理解就是在页面跳转的时候&#xff0c;增加一级拦截器&#xff0c;实现一些自定义的功能&#xff0c;其中最重要的就是判断跳转的页面是否需要登录后查看&#xff0c;如果需要登录后查看且此时系统并未登录&#xff0c;就需要跳转到登录页&…