当前位置: 首页 > news >正文

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 组件中,我们会使用 useContextuseState 来管理状态,并通过调用接口将结果赋值给 useState 的变量 value。然后在 B 组件中,将 C 组件包裹在 A 组件内,使得 C 组件能够通过 useContext 获取 value 的值。

以下是详细的实现步骤和代码示例:

1. 创建 A 组件并封装 Context

首先,在 A 组件中,我们会创建一个 Context,然后使用 useState 来管理状态,并在 useEffect 中调用接口获取数据,将结果存储在 value 中。最后,我们通过 Context.Providervalue 传递给子组件。

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 组件会显示接口返回的 titlebody 信息。

这个实现方案清晰地展示了如何在 React 中使用 createContext 封装组件,并在子组件中获取并使用封装组件中的状态数据。

案例 2: createContext封装 A组件 ,在A组件里 请求接口结果 赋值 useState 的变量 value。 然后在B组件 获取使用 A组件里的 变量value 的值

要在 React 中实现 createContext 封装的 A 组件,并在 B 组件中获取并使用 A 组件中的 value 值,你可以按照以下步骤进行。

1. 创建 A 组件并封装 Context

首先,创建 A 组件,并在其中使用 useContextuseState 来管理状态。通过 useEffect 调用接口,将返回的数据存储在 value 中。然后通过 Context.Providervalue 传递给 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.Providervalue 传递给子组件。
  • useMyContext 自定义 Hook:这是一个简单的 Hook,方便在 B 组件中直接获取 MyContext 的值。
  • B 组件:在 B 组件中,通过 useMyContext 获取 A 组件中的 value 值,然后展示出来。如果 value 为空,则显示 Loading...
4. 运行效果

当你运行这个示例时,B 组件会首先显示 Loading...。一旦 A 组件完成数据请求并赋值 value 后,B 组件会显示接口返回的 titlebody 信息。

这种方法通过 createContext 以及 Context.Provider 实现了在不同组件间的状态共享,并避免了繁琐的 props 传递,代码结构更加清晰且易于维护。

相关文章:

React.createContext 的 多种使用方法 详细实现方案代码

React.createContext 是 React 的上下文 API 的核心方法之一&#xff0c;提供了一种无需通过组件树逐层传递 props 的方式来共享数据。它特别适合于全局状态的管理&#xff0c;比如用户信息、主题设置等。下面我将详细介绍 React.createContext 的多种使用方法&#xff0c;并提…...

计算机网络之IPv4深度解析

一.IP地址 IP地址的组成方式&#xff1a;网络号 主机号 可以这样理解&#xff0c;根据网络号找路由器&#xff0c;根据主机号找连着路由器的主机 早期分类的IP地址 表示如下&#xff1a; 其中&#xff0c;有些特殊的IP地址&#xff1a; 主机号全为0&#xff0c;表示本网…...

TinyGPT-V:微型视觉语言模型【VLM】

AI技术正在不断融入我们的日常生活。人工智能的一个应用包括多模态化&#xff0c;例如将语言与视觉模型相结合。这些视觉语言模型可以应用于视频字幕、语义搜索等任务。 本周&#xff0c;我将重点介绍一种名为 TinyGPT-V&#xff08;Arxiv | GitHub&#xff09;的最新视觉语言…...

pytorch自动微分

一、torch.autograd.backward(tensors, grad_tensorsNone, retain_graphNone, create_graphFalse)功能&#xff1a;自动求取梯度 grad_tensors&#xff1a;多梯度权重 # 自动求取梯度 # import torch # w torch.tensor([1.],requires_gradTrue) # x torch.tensor([2.],requir…...

TCP协议为什么是三次握手和四次挥手

1.一次握手&&二次握手 一次握手就能成功的话&#xff0c;也就代表着不需要进行确认&#xff0c;那么万一有恶意的服务器一直发送SYN&#xff0c;而服务器需要维护大量的连接&#xff0c;维护连接又需要成本&#xff0c;那么就很容易引发SYN洪水&#xff0c;导致服务器…...

利用ChatGPT提升学术论文撰写效率:从文献搜集到综述撰写的全面指南

大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾学术科研AI实操的学术人。关于使用ChatGPT等AI学术科研的相关问题可以和作者七哥(yida985)交流,多多交流,相互成就,共同进步,为大家带来最酷最有效的智能AI学术科研写作攻略。 本文旨在介绍如何利用AI辅助工具,…...

智能、高效、安全,企业桌面软件管理系统,赋能企业数字化转型!提升工作效率不是梦!

为了在激烈的市场竞争中脱颖而出&#xff0c;实现可持续发展&#xff0c;数字化转型已成为企业不可或缺的战略选择&#xff01;而在这一过程中&#xff0c;一款智能、高效、安全的企业桌面软件管理系统&#xff0c;如安企神&#xff0c;正逐步成为企业数字化转型的重要驱动力。…...

第N7周:调用Gensim库训练Word2Vec模型

本文为365天深度学习训练营 中的学习记录博客原作者&#xff1a;K同学啊 任务&#xff1a; ●1. 阅读NLP基础知识里Word2vec详解一文&#xff0c;了解并学习Word2vec相关知识 ●2. 创建一个.txt文件存放自定义词汇&#xff0c;防止其被切分 数据集&#xff1a;选择《人民的名义…...

基于Crontab调度,实现Linux下的定时任务执行。

文章目录 引言I 预备知识Crontab的基本组成Crontab的配置文件格式Crontab的配置文件Crontab不可引用环境变量杀死进程命令II Crontab实践案例Crontab工具的使用重启tomcat服务每分钟都打印当前时间到一个文件中30s执行一次III 常见问题并发冗余执行任务&& 和|| 和 ;的区…...

Centos系统中创建定时器完成定时任务

Centos系统中创建定时器完成定时任务 时间不一定能证明很多东西&#xff0c;但是一定能看透很多东西&#xff0c;坚信自己的选择&#xff0c;不动摇&#xff0c;使劲跑&#xff0c;明天会更好。 在 CentOS 上&#xff0c;可以使用 systemd 定时器来创建一个每十秒执行一次的任务…...

WLAN基础知识(1)

WLAN&#xff1a; 无线局域网&#xff0c;无线技术&#xff1a;Wi-Fi、红外、蓝牙等 WLAN设备&#xff1a; 胖AP&#xff1a; 适用于家庭等小型网络&#xff0c;可独立配置&#xff0c;如&#xff1a;家用Wi-Fi路由器 瘦AP&#xff1a; 适用于大中型企业&#xff0c;需要配合AC…...

网络安全实训第三天(文件上传、SQL注入漏洞)

1 文件上传漏洞 准备一句话文件wjr.php.png&#xff0c;进入到更换头像的界面&#xff0c;使用BP拦截选择文件的请求 拦截到请求后将wjr.php.png修改为wjr.php&#xff0c;进行转发 由上图可以查看到上传目录为网站目录下的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

摘 要 提起伊犁&#xff0c;很多人常说&#xff0c;不去新疆&#xff0c;你就不知道中国有多美&#xff0c;不去伊犁&#xff0c;你就不知道新疆有多美。在这里你可以看到中国最美的景色。如果可可托海海是一个野性和粗犷的战士&#xff0c;那么那拉提一定是一个温柔和玉般的绅…...

提升工作效率的五大神器

在这个信息爆炸、节奏加速的时代&#xff0c;高效工作已经成为了职场人士追求的目标。如何在短时间内完成更多的工作任务&#xff0c;同时保持高质量的输出&#xff1f;答案在于合理利用工具。以下是五个能够显著提升工作效率的软件推荐&#xff0c;它们各自在任务管理、团队协…...

想投资现货黄金?在TMGM开户需要多少钱?

最近&#xff0c;越来越多的人开始关注黄金投资&#xff0c;希望通过黄金来对冲风险、保值增值。而选择一家可靠的交易平台是进行黄金投资的第一步。TMGM作为全球知名的外汇交易商&#xff0c;也为投资者提供了黄金交易服务。那么&#xff0c;在TMGM开户投资黄金&#xff0c;需…...

“零拷贝”

1、python利用0拷贝提高效率 在Python中&#xff0c;“零拷贝”&#xff08;Zero-Copy&#xff09;通常是指一种数据处理技术&#xff0c;它允许数据从一个地方传输到另一个地方而不需要创建额外的数据副本。这可以显著减少内存带宽的使用并提高性能&#xff0c;尤其是在处理大…...

[ABC367C] Enumerate Sequences 题解

[ABC367C] Enumerate Sequences 搜索。 考虑使用 DFS 深搜&#xff0c;对于第 i i i 个数&#xff0c;从 1 1 1 到 r i r_i ri​ 枚举&#xff0c;将 a i a_i ai​ 设为当前枚举的数&#xff0c;并进行下一层递归。 对所有的数填完后&#xff0c;判断当前和是否为 k k …...

C语言 | Leetcode C语言题解之第336题回文对

题目&#xff1a; 题解&#xff1a; #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 表&#xff1a; ------------------- | Column Name | Type | ------------------- | num | int | ------------------- 该表可能包含重复项&#xff08;换句话说&#xff0c;在SQL中&#xff0c;该表没有主键&#xff09;。…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...