React.createContext 的 多种使用方法 详细实现方案代码
React.createContext 是 React 的上下文 API 的核心方法之一,提供了一种无需通过组件树逐层传递 props 的方式来共享数据。它特别适合于全局状态的管理,比如用户信息、主题设置等。下面我将详细介绍 React.createContext 的多种使用方法,并提供相应的代码示例。
1. 基础使用
- 目的:在父组件中定义一个
Context,子组件可以直接通过useContext来获取上下文中的数据。
示例:
import React, { createContext, useContext } from 'react';// 创建一个 Context
const MyContext = createContext();const GrandChild = () => {const value = useContext(MyContext); // 使用 useContext 获取数据return <div>{value}</div>;
};const Child = () => <GrandChild />;const Parent = () => {const contextValue = "Hello from Context";return (<MyContext.Provider value={contextValue}><Child /></MyContext.Provider>);
};export default Parent;
2. 使用 Context 传递对象
- 目的:在 Context 中传递一个复杂的数据结构,比如对象或数组。
示例:
import React, { createContext, useContext } from 'react';// 创建一个 Context
const UserContext = createContext();const UserProfile = () => {const user = useContext(UserContext); // 使用 useContext 获取对象return (<div><p>Name: {user.name}</p><p>Age: {user.age}</p></div>);
};const Parent = () => {const user = { name: "John Doe", age: 30 };return (<UserContext.Provider value={user}><UserProfile /></UserContext.Provider>);
};export default Parent;
3. 使用 Context 与 useState 配合
- 目的:在 Context 中传递动态状态,可以在组件中修改 Context 中的数据。
示例:
import React, { createContext, useContext, useState } from 'react';// 创建一个 Context
const CounterContext = createContext();const CounterDisplay = () => {const [count] = useContext(CounterContext); // 通过 useContext 获取 countreturn <div>Count: {count}</div>;
};const CounterControls = () => {const [, setCount] = useContext(CounterContext); // 通过 useContext 获取 setCountreturn (<button onClick={() => setCount(prev => prev + 1)}>Increment</button>);
};const Parent = () => {const counterState = useState(0); // 使用 useState 创建计数器状态return (<CounterContext.Provider value={counterState}><CounterDisplay /><CounterControls /></CounterContext.Provider>);
};export default Parent;
4. 多 Context 配合使用
- 目的:在一个组件中使用多个 Context,分别传递不同的状态或数据。
示例:
import React, { createContext, useContext } from 'react';// 创建两个 Context
const ThemeContext = createContext();
const UserContext = createContext();const Dashboard = () => {const theme = useContext(ThemeContext);const user = useContext(UserContext);return (<div style={{ background: theme.background, color: theme.color }}><p>Welcome, {user.name}</p></div>);
};const Parent = () => {const theme = { background: "black", color: "white" };const user = { name: "Jane Doe" };return (<ThemeContext.Provider value={theme}><UserContext.Provider value={user}><Dashboard /></UserContext.Provider></ThemeContext.Provider>);
};export default Parent;
5. Context API 与 useReducer 结合
- 目的:在复杂状态管理中,通过
useReducer管理状态,并将其与 Context 结合使用。
示例:
import React, { createContext, useContext, useReducer } from 'react';// 创建一个 Context
const CounterContext = createContext();// 定义 reducer 函数
const counterReducer = (state, action) => {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:return state;}
};const CounterDisplay = () => {const { state } = useContext(CounterContext); // 获取 statereturn <div>Count: {state.count}</div>;
};const CounterControls = () => {const { dispatch } = useContext(CounterContext); // 获取 dispatchreturn (<><button onClick={() => dispatch({ type: 'increment' })}>Increment</button><button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button></>);
};const Parent = () => {const [state, dispatch] = useReducer(counterReducer, { count: 0 }); // 使用 useReducerreturn (<CounterContext.Provider value={{ state, dispatch }}><CounterDisplay /><CounterControls /></CounterContext.Provider>);
};export default Parent;
6. 全局 Context
- 目的:创建一个全局的 Context,通常用于应用级别的状态管理,比如用户认证信息。
示例:
import React, { createContext, useContext, useState } from 'react';// 创建全局 Context
const AuthContext = createContext();export const useAuth = () => {return useContext(AuthContext); // 自定义 Hook 方便使用
};const AuthProvider = ({ children }) => {const [isAuthenticated, setAuthenticated] = useState(false);const login = () => setAuthenticated(true);const logout = () => setAuthenticated(false);return (<AuthContext.Provider value={{ isAuthenticated, login, logout }}>{children}</AuthContext.Provider>);
};const Dashboard = () => {const { isAuthenticated, logout } = useAuth();return (<div>{isAuthenticated ? (<><p>Welcome, User!</p><button onClick={logout}>Logout</button></>) : (<p>Please log in.</p>)}</div>);
};const App = () => {return (<AuthProvider><Dashboard /></AuthProvider>);
};export default App;
这些例子展示了 React.createContext 的多种使用方法,从简单的数据共享到复杂的状态管理,希望能帮助你更好地理解和应用 Context API。
7.例子:
案例 1: createContext封装 A组件 ,在A组件里 请求接口结果 赋值 useState 的变量 value。 然后在B组件 使用 A组件 包裹 C组件 在 C组件 获取使用 A组件里的 变量value 的值
你可以通过封装 Context 来实现这个功能。在 A 组件中,我们会使用 useContext 和 useState 来管理状态,并通过调用接口将结果赋值给 useState 的变量 value。然后在 B 组件中,将 C 组件包裹在 A 组件内,使得 C 组件能够通过 useContext 获取 value 的值。
以下是详细的实现步骤和代码示例:
1. 创建 A 组件并封装 Context
首先,在 A 组件中,我们会创建一个 Context,然后使用 useState 来管理状态,并在 useEffect 中调用接口获取数据,将结果存储在 value 中。最后,我们通过 Context.Provider 将 value 传递给子组件。
import React, { createContext, useState, useEffect, useContext } from 'react';// 创建 Context
const MyContext = createContext();// 封装 A 组件
export const A = ({ children }) => {const [value, setValue] = useState(null);useEffect(() => {// 模拟请求接口,获取数据const fetchData = async () => {const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');const data = await response.json();setValue(data);};fetchData();}, []);return (<MyContext.Provider value={value}>{children}</MyContext.Provider>);
};// 创建自定义 Hook 方便获取 Context 值
export const useMyContext = () => {return useContext(MyContext);
};
2. 在 B 组件中使用 A 组件包裹 C 组件
在 B 组件中,我们将 C 组件包裹在 A 组件内,使 C 组件能够访问 A 组件中的 value 值。
import React from 'react';
import { A } from './A'; // 引入 A 组件
import C from './C'; // 引入 C 组件const B = () => {return (<A><C /></A>);
};export default B;
3. 在 C 组件中获取 value 的值
在 C 组件中,我们通过 useMyContext 自定义 Hook 获取 A 组件中的 value 值,并将其展示在界面上。
import React from 'react';
import { useMyContext } from './A'; // 使用自定义 Hook 获取 Context 值const C = () => {const value = useMyContext();return (<div>{value ? (<div><h1>{value.title}</h1><p>{value.body}</p></div>) : (<p>Loading...</p>)}</div>);
};export default C;
4. 最终的结构
最终的组件层级结构是:
B组件使用A组件包裹C组件。A组件负责请求数据并通过Context传递数据。C组件通过useMyContext获取A组件中的value值并展示。
5. 运行效果
当你运行这个示例时,C 组件会首先显示 Loading...,在 A 组件成功请求接口并赋值 value 后,C 组件会显示接口返回的 title 和 body 信息。
这个实现方案清晰地展示了如何在 React 中使用 createContext 封装组件,并在子组件中获取并使用封装组件中的状态数据。
案例 2: createContext封装 A组件 ,在A组件里 请求接口结果 赋值 useState 的变量 value。 然后在B组件 获取使用 A组件里的 变量value 的值
要在 React 中实现 createContext 封装的 A 组件,并在 B 组件中获取并使用 A 组件中的 value 值,你可以按照以下步骤进行。
1. 创建 A 组件并封装 Context
首先,创建 A 组件,并在其中使用 useContext 和 useState 来管理状态。通过 useEffect 调用接口,将返回的数据存储在 value 中。然后通过 Context.Provider 将 value 传递给 B 组件。
import React, { createContext, useState, useEffect } from 'react';// 创建 Context
const MyContext = createContext();// 封装 A 组件
export const A = ({ children }) => {const [value, setValue] = useState(null);useEffect(() => {// 模拟请求接口,获取数据const fetchData = async () => {const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');const data = await response.json();setValue(data);};fetchData();}, []);return (<MyContext.Provider value={value}>{children}</MyContext.Provider>);
};// 创建自定义 Hook 方便获取 Context 值
export const useMyContext = () => {return React.useContext(MyContext);
};
2. 在 B 组件中获取 value 的值
在 B 组件中,使用 A 组件包裹内容,并通过 useMyContext 自定义 Hook 获取 value 的值。
import React from 'react';
import { A, useMyContext } from './A'; // 引入 A 组件和自定义 Hookconst B = () => {const value = useMyContext(); // 获取 A 组件中的 valuereturn (<A><div>{value ? (<div><h1>{value.title}</h1><p>{value.body}</p></div>) : (<p>Loading...</p>)}</div></A>);
};export default B;
3. 代码解释
- A 组件:通过
createContext创建了一个上下文MyContext。在A组件内部,使用useState来定义value,通过useEffect调用接口将数据保存到value中。最后,通过MyContext.Provider将value传递给子组件。 - useMyContext 自定义 Hook:这是一个简单的 Hook,方便在
B组件中直接获取MyContext的值。 - B 组件:在
B组件中,通过useMyContext获取A组件中的value值,然后展示出来。如果value为空,则显示Loading...。
4. 运行效果
当你运行这个示例时,B 组件会首先显示 Loading...。一旦 A 组件完成数据请求并赋值 value 后,B 组件会显示接口返回的 title 和 body 信息。
这种方法通过 createContext 以及 Context.Provider 实现了在不同组件间的状态共享,并避免了繁琐的 props 传递,代码结构更加清晰且易于维护。
相关文章:
React.createContext 的 多种使用方法 详细实现方案代码
React.createContext 是 React 的上下文 API 的核心方法之一,提供了一种无需通过组件树逐层传递 props 的方式来共享数据。它特别适合于全局状态的管理,比如用户信息、主题设置等。下面我将详细介绍 React.createContext 的多种使用方法,并提…...
计算机网络之IPv4深度解析
一.IP地址 IP地址的组成方式:网络号 主机号 可以这样理解,根据网络号找路由器,根据主机号找连着路由器的主机 早期分类的IP地址 表示如下: 其中,有些特殊的IP地址: 主机号全为0,表示本网…...
TinyGPT-V:微型视觉语言模型【VLM】
AI技术正在不断融入我们的日常生活。人工智能的一个应用包括多模态化,例如将语言与视觉模型相结合。这些视觉语言模型可以应用于视频字幕、语义搜索等任务。 本周,我将重点介绍一种名为 TinyGPT-V(Arxiv | GitHub)的最新视觉语言…...
pytorch自动微分
一、torch.autograd.backward(tensors, grad_tensorsNone, retain_graphNone, create_graphFalse)功能:自动求取梯度 grad_tensors:多梯度权重 # 自动求取梯度 # import torch # w torch.tensor([1.],requires_gradTrue) # x torch.tensor([2.],requir…...
TCP协议为什么是三次握手和四次挥手
1.一次握手&&二次握手 一次握手就能成功的话,也就代表着不需要进行确认,那么万一有恶意的服务器一直发送SYN,而服务器需要维护大量的连接,维护连接又需要成本,那么就很容易引发SYN洪水,导致服务器…...
利用ChatGPT提升学术论文撰写效率:从文献搜集到综述撰写的全面指南
大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾学术科研AI实操的学术人。关于使用ChatGPT等AI学术科研的相关问题可以和作者七哥(yida985)交流,多多交流,相互成就,共同进步,为大家带来最酷最有效的智能AI学术科研写作攻略。 本文旨在介绍如何利用AI辅助工具,…...
智能、高效、安全,企业桌面软件管理系统,赋能企业数字化转型!提升工作效率不是梦!
为了在激烈的市场竞争中脱颖而出,实现可持续发展,数字化转型已成为企业不可或缺的战略选择!而在这一过程中,一款智能、高效、安全的企业桌面软件管理系统,如安企神,正逐步成为企业数字化转型的重要驱动力。…...
第N7周:调用Gensim库训练Word2Vec模型
本文为365天深度学习训练营 中的学习记录博客原作者:K同学啊 任务: ●1. 阅读NLP基础知识里Word2vec详解一文,了解并学习Word2vec相关知识 ●2. 创建一个.txt文件存放自定义词汇,防止其被切分 数据集:选择《人民的名义…...
基于Crontab调度,实现Linux下的定时任务执行。
文章目录 引言I 预备知识Crontab的基本组成Crontab的配置文件格式Crontab的配置文件Crontab不可引用环境变量杀死进程命令II Crontab实践案例Crontab工具的使用重启tomcat服务每分钟都打印当前时间到一个文件中30s执行一次III 常见问题并发冗余执行任务&& 和|| 和 ;的区…...
Centos系统中创建定时器完成定时任务
Centos系统中创建定时器完成定时任务 时间不一定能证明很多东西,但是一定能看透很多东西,坚信自己的选择,不动摇,使劲跑,明天会更好。 在 CentOS 上,可以使用 systemd 定时器来创建一个每十秒执行一次的任务…...
WLAN基础知识(1)
WLAN: 无线局域网,无线技术:Wi-Fi、红外、蓝牙等 WLAN设备: 胖AP: 适用于家庭等小型网络,可独立配置,如:家用Wi-Fi路由器 瘦AP: 适用于大中型企业,需要配合AC…...
网络安全实训第三天(文件上传、SQL注入漏洞)
1 文件上传漏洞 准备一句话文件wjr.php.png,进入到更换头像的界面,使用BP拦截选择文件的请求 拦截到请求后将wjr.php.png修改为wjr.php,进行转发 由上图可以查看到上传目录为网站目录下的upload/avator,查看是否上传成功 使用时间戳在线工具…...
Nginx 学习之 配置支持 IPV6 地址
目录 搭建并测试1. 下载 NG 安装包2. 安装编译工具及库文件3. 上传并解压安装包4. 编译5. 安装6. 修改配置7. 启动 NG8. 查看 IP 地址9. 测试 IP 地址9.1. 测试 IPV4 地址9.2. 测试 IPV6 地址 IPV6 测试失败原因1. curl: [globbing] error: bad range specification after pos …...
springboot+伊犁地区游客小助手-小程序—计算机毕业设计源码无偿分享需要私信20888
摘 要 提起伊犁,很多人常说,不去新疆,你就不知道中国有多美,不去伊犁,你就不知道新疆有多美。在这里你可以看到中国最美的景色。如果可可托海海是一个野性和粗犷的战士,那么那拉提一定是一个温柔和玉般的绅…...
提升工作效率的五大神器
在这个信息爆炸、节奏加速的时代,高效工作已经成为了职场人士追求的目标。如何在短时间内完成更多的工作任务,同时保持高质量的输出?答案在于合理利用工具。以下是五个能够显著提升工作效率的软件推荐,它们各自在任务管理、团队协…...
想投资现货黄金?在TMGM开户需要多少钱?
最近,越来越多的人开始关注黄金投资,希望通过黄金来对冲风险、保值增值。而选择一家可靠的交易平台是进行黄金投资的第一步。TMGM作为全球知名的外汇交易商,也为投资者提供了黄金交易服务。那么,在TMGM开户投资黄金,需…...
“零拷贝”
1、python利用0拷贝提高效率 在Python中,“零拷贝”(Zero-Copy)通常是指一种数据处理技术,它允许数据从一个地方传输到另一个地方而不需要创建额外的数据副本。这可以显著减少内存带宽的使用并提高性能,尤其是在处理大…...
[ABC367C] Enumerate Sequences 题解
[ABC367C] Enumerate Sequences 搜索。 考虑使用 DFS 深搜,对于第 i i i 个数,从 1 1 1 到 r i r_i ri 枚举,将 a i a_i ai 设为当前枚举的数,并进行下一层递归。 对所有的数填完后,判断当前和是否为 k k …...
C语言 | Leetcode C语言题解之第336题回文对
题目: 题解: #define SIZE 9470 #define N 168000 #define P 13331typedef unsigned long long ULL; ULL p[301];//p[i]存储P^ivoid init()//初始化p进制次幂数组 {int i;p[0]1;for(i1;i<300;i){p[i]p[i-1]*P;} }int** palindromePairs(char**words,…...
【SQL】仅出现一次的最大数据
目录 题目 分析 代码 题目 MyNumbers 表: ------------------- | Column Name | Type | ------------------- | num | int | ------------------- 该表可能包含重复项(换句话说,在SQL中,该表没有主键)。…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
