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中,该表没有主键)。…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...
作为点的对象CenterNet论文阅读
摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表,并对每一个位置进行分类。这种做法既浪费又低效,并且需要额外的后处理。在本文中,我们采取了不同的方法。我们将物体建模为单…...
codeforces C. Cool Partition
目录 题目简述: 思路: 总代码: https://codeforces.com/contest/2117/problem/C 题目简述: 给定一个整数数组,现要求你对数组进行分割,但需满足条件:前一个子数组中的值必须在后一个子数组中…...
JS的传统写法 vs 简写形式
一、条件判断与逻辑操作 三元运算符简化条件判断 // 传统写法 let result; if (someCondition) {result yes; } else {result no; }// 简写方式 const result someCondition ? yes : no;短路求值 // 传统写法 if (condition) {doSomething(); }// 简写方式 condition &…...
【Flask】:轻量级Python Web框架详解
什么是Flask? Flask是一个用Python编写的轻量级Web应用框架。它被称为"微框架"(microframework),因为它核心简单但可扩展性强,不强制使用特定的项目结构或库。Flask由Armin Ronacher开发,基于Werkzeug WSGI工具包和Jin…...
