React中也许你会用到的Context

文章概叙

本文主要是写React中Context的概念以及使用,请一定搞清楚什么时候使用Context

Context的介绍

通常来说,你会通过 props 将信息从父组件传递到子组件。但是,如果你必须通过许多中间组件向下传递
props,或是在你应用中的许多组件需要相同的信息,传递 props 会变得十分冗长和不便。Context
允许父组件向其下层无论多深的任何组件提供信息,而无需通过 props 显式传递。

顾名思义,Context的意思是上下文,在以组件为主的React中,Context的作用就如同props一样,将属性传递过去,只是Context的范围更广阔,可以实现根节点对下属多个子节点的属性传递,当然,如果想要实现全局的属性传递,Redux无疑是更适合的。

上下文使得组件能够无需通过显式传递参数的方式 将信息逐层传递。

Context 可以让父节点,甚至是很远的父节点都可以为其内部的整个组件树提供数据。

在这里插入图片描述

上图是官网拿过来的,很完美地解释了Context的辐射区域。

了解了Context的作用范围,接下来会创建一个如上图所述的结构来阐述Context的使用方法。

创建Context

既然要讨论Context,第一步势必要创建一个Context,但是需要确定好Context的对象,也就是我们的Context的“根”要放在哪儿。一般来说,是放在我们需要读取属性的根节点,这次的Demo会放在名为Pcomponent的组件下。

创建context,我们需要使用到createContext来创建一个Context,而这个API需要传递一个默认参数,下面会传入如下的对象。

{name: "mk",emial: "mk@xxx.com",department: "IT"
}

需要注意的是,我们需要将createContext返回的参数导出去,别的地方会用到。

import React, { createContext } from "react";
import Scomponent from "../Scomponent";function Pcomponent() {return (<><Scomponent></Scomponent></>);
}
export default Pcomponent;export const userContext = createContext({name: "mk",email: "mk@xxx.com",department: "IT",
});

使用Context

无意外,既然有抛出,那就有接收以及使用,使用Context需要用到一个名为useContext的hook,且需要在当前的组件中引入我们刚刚创建的context。

import { useContext } from "react";
import { userContext } from "./../Pcomponent";function Scomponent() {const user = useContext(userContext);return (<><p>name:{user?.name}</p><p>email:{user?.email}</p><p>department:{user?.department}</p></>);
}
export default Scomponent;

当前效果如下

在这里插入图片描述

看起来,我们的效果实现了,可以在a组件读取到b组件的数据,而且还不限制于是否为根组件的关系。

但是请注意,我们当前的效果并没有什么用,因为我们用一个export跟import也可以实现这么一个“初始化”的跨组件读取效果,而且这个是一个永远不会变的初始化效果

上下文之所以有用,是因为可以 提供来自其他组件的其他的、动态变化的值

Provider包裹组件

用上下文 provider 包裹组件,为里面所有的组件指定一个上下文的值
我们需要使用Provider,在Pcomponent中将Scomponent包裹起来,为其指定一个上下文,且在下面的代码中,会使用到useState这个Hook,作用是方便进行数据的更新。

import React, { createContext, useState } from "react";
import Scomponent from "../Scomponent";
const initData = {name: "mk",email: "mk@xxx.com",department: "IT",
};
function Pcomponent() {const [userInfo, setUserInfo] = useState(initData);return (<userContext.Provider value={{ userInfo, setUserInfo }}><Scomponent></Scomponent></userContext.Provider>);
}
export default Pcomponent;
export const userContext = createContext<any>(initData);

上述的代码中,第三行到第七行,我们将初始化的状态抽离出来,封装成一个初始化的数据。在第17行中设置了context的初始化数据。

最重要的代码在于第11行中,使用provider作为context的"载体",这告诉了React,当你在下面设置了读取上下文的时候,请使用这儿设置的userContext.且value属性为传递值,并且设置了更新的方法,以便在其他组件中可以更新根组件中的属性。
接着,在子组件中,我们也需要对我们的代码做一些小小的更新。

import { useContext } from "react";
import { userContext } from "./../Pcomponent";function Scomponent() {const user = useContext(userContext);return (<><p>name:{user?.userInfo?.name}</p><p>email:{user?.userInfo?.email}</p><p>department:{user?.userInfo?.department}</p><buttononClick={() => {user.setUserInfo({...user.userInfo,name: user?.userInfo?.name + "1",});}}>更新数据</button></>);
}
export default Scomponent;

其中,由于使用Provider传进来的参数已经变成了两种,其中一个为数据,一个为更新数据的方法,所以在页面中,也需要进行更改。

效果如下:

在这里插入图片描述

现在,对于Context的使用到此结束了,你对context的使用程度应该到了可以上手的地步了。

当涉及到多个context的使用,我更建议使用redux或者是useReducer,如果单纯的使用多个Context的话,代码结构上很乱。
接着,会增加一个P2component组件,测试Context的范围。

为了方便测试,下面的代码会直接放在app.tsx中。

import React from "react";
import "./App.css";
import Pcomponent from "./components/Pcomponent";
import P2component from "./components/P2component";function App() {return (<div className="App"><Pcomponent></Pcomponent><P2component></P2component><hr/></div>);
}
export default App;

P2component的内容如下,只是简单的引用了Scomponent。

import React from "react";
import Scomponent from "../Scomponent";function P2component({ children }: any) {return <Scomponent></Scomponent>;
}
export default P2component;

在这里插入图片描述

可见,由于p2component中没有提供provider,所以在下面的组件中就没有Context的效果。而出现了useContext"无效"的感觉.

古老的Consumer

在 useContext 之前,有一种更老的方法来读取上下文:

function Button() {// 🟡 遗留方式 (不推荐)return (<ThemeContext.Consumer>{theme => (<button className={theme} />)}</ThemeContext.Consumer>);
}

怎么看都觉得使用useContext更加简洁、方便…且我记得这个是以前函数组件才用的,虽然以前组件基本都用类组件…

最后的叮嘱

与redux相同,并不是说一个项目中使用了provider就很高大上,在使用provider中,需要考虑是否组件结构合理,如上述的例子,一个props就可以解决了。

在开发中,我们也经常使用useReducer跟useContext进行开发,但是由于介绍reducer的话,篇幅会更长,所以就直接用useState来举例子了。

个人博客

公众号文章链接

各位大佬好,我又来求关注了,希望各位大佬关注下我的公众号,冬至快乐~

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

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

相关文章

OCC:第一个程序,对话框中显示一个BOX

1. OCC库的获取 从github上获取 gitgithub.com:tpaviot/oce.git&#xff0c;自己编译官网获取二进制包&#xff08;获取下来的只有release 版本的&#xff0c;而且VS版本不一定适合自己&#xff09;官网源码&#xff0c;然后自己编译&#xff08;稍微折腾点&#xff0c;建议按…

阻塞 IO(BIO)

文章目录 阻塞 IO(BIO)模型等待队列头init_waitqueue_headDECLARE_WAIT_QUEUE_HEAD 等待队列项使用方法驱动程序应用程序模块使用参考 阻塞 IO(BIO) 模型 等待队列是内核实现阻塞和唤醒的内核机制。 等待队列以循环链表为基础结构&#xff0c;链表头和链表项分别为等待队列头和…

深入了解UI标签栏设计细节:你不能错过的要点

UI 标签栏的作用有哪些&#xff1f; 导航是移动 UI 中最常见的组成部分&#xff0c;通常放置在 UI 标签栏上&#xff0c;以帮助我们在不同的页面之间切换。UI 标签栏可以保持界面的可控性&#xff0c;并提高可用性。简而言之&#xff0c;UI 标签栏可以加强交互&#xff0c;让用…

轻量Http客户端工具VSCode和IDEA

文章目录 前言Visual Studio Code 的插件 REST Client编写第一个案例进阶&#xff0c;设置变量进阶&#xff0c;设置Token 前言 作为一个WEB工程师&#xff0c;在日常的使用过程中&#xff0c;HTTP请求是必不可少的。我们采用的HTTP工具有如下&#xff1a; Postman Insomnia Ap…

CSS3多列分页属性

CSS3多列 Firefox浏览器支持该属性的形式是-moz-column-count&#xff0c;而基于Webkit的浏览器&#xff0c;例如Safari和Chrome&#xff0c;支持该属性的形式是-webkit-column-count column-count&#xff1a;该属性定义多列文本流中的栏数 语法&#xff1a;column-count:int…

YACS(上海计算机学会竞赛平台)三星级挑战——两数之和

题目描述 给定 n 个整数 a[1]​,a[2]​,⋯,a[n]​&#xff0c;并且保证 a[1​]≤a[2​]≤⋯≤a[n]​ 再给定一个目标值 t&#xff0c;请判断能否找到 a[i]​ 与 a[j]​&#xff0c;ai​aj​t 且 i≠j。 输入格式 第一行&#xff1a;单个整数n&#xff1b; 第二行&#xf…

智能优化算法应用:基于卷尾猴算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于卷尾猴算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于卷尾猴算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.卷尾猴算法4.实验参数设定5.算法结果6.参考文…

C++ 函数重载、操作符重载

依然是温故而知新&#xff0c;不过现在更多的是以此为乐的心态啦。本篇通过代码实例&#xff0c;展示c函数重载相关知识&#xff0c;包括构造函数的重载、操作符重载等。 在构造函数重载中&#xff0c;给大家带来点稍微提升的用法&#xff0c; 看了不吃亏&#xff0c;看了不上当…

如何快速实现地源热泵远程监控

地源热泵远程监控解决方案 一、项目背景 山东省潍坊市盛世花园小区地源热泵项目是一个先进的供暖与制冷系统&#xff0c;旨在为整个小区提供高效且节能的温控服务。该系统主要由地下管道网络、地源热泵单元以及室内分配系统组成。 针对现有的地源热泵系统的管理和监控问题&a…

110基于matlab的混合方法组合的极限学习机和稀疏表示进行分类

基于matlab的混合方法组合的极限学习机和稀疏表示进行分类。通过将极限学习机&#xff08;ELM&#xff09;和稀疏表示&#xff08;SRC&#xff09;结合到统一框架中&#xff0c;混合分类器具有快速测试&#xff08;ELM的优点&#xff09;的优点&#xff0c;且显示出显着的分类精…

【NAM】《NAM:Normalization-based Attention Module》

NeurIPS-2021 workshop 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method5 Experiments5.1 Datasets and Metrics5.2 Experiments 6 Conclusion&#xff08;own&#xff09; 1 Background and Motivation 注意力机制是近些年视觉领域…

WPF组合控件TreeView+DataGrid之DataGrid封装

&#xff08;关注博主后&#xff0c;在“粉丝专栏”&#xff0c;可免费阅读此文&#xff09; wpf的功能非常强大&#xff0c;很多控件都是原生的&#xff0c;但是要使用TreeViewDataGrid的组合&#xff0c;就需要我们自己去封装实现。 我们需要的效果如图所示&#x…

[python]python实现对jenkins 的任务触发

目录 关键词平台说明背景一、安装 python-jenkins 库二、code三、运行 Python 脚本四、注意事项 关键词 python、excel、DBC、jenkins 平台说明 项目Valuepython版本3.6 背景 用python实现对jenkins 的任务触发。 一、安装 python-jenkins 库 pip install python-jenkin…

论文解读:Informer-AAAI2021年最佳论文

论文背景 应用背景 训练的是历史数据&#xff0c;但预测的是未来的数据&#xff0c;但是历史数据和未来数据的分布不一定是一样的&#xff0c;所以时间序列应用于股票预测往往不太稳定 动作预测&#xff1a; 基于之前的视频中每一帧动作&#xff0c;预测下一帧这个人要做什么…

Ubuntu 常用命令之 echo 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 echo 是一个在 Ubuntu 系统下常用的命令&#xff0c;主要用于在终端输出字符串或者变量。 echo 的基本语法 echo [option] [string]echo 命令的参数包括 -n&#xff1a;不输出结尾的换行符。-e&#xff1a;启用反斜杠转义字符。…

超级逼真人脸生成,Stable Diffusion的3个关键技巧

大家好&#xff0c;你是否曾想过&#xff0c;为什么别人可以使用AI图像生成技术生成如此逼真的人脸&#xff0c;而自己的尝试却充满了错误和瑕疵&#xff0c;让人一眼看出是假的。尝试过调整提示和设置&#xff0c;但似乎仍无法与他人的质量相匹配。 本文将带大家了解使用Stab…

LeetCode-17 电话号码的字母组合

LeetCode-17 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;d…

硬件产品经理:硬件产品敏捷开发

目录 简介 敏捷 CSDN学院 作者简介 简介 之所以敏捷产品开发流程会越来越普遍。 主要得益于这个方法可以让企业使用更少的资源去开发出令客户满意的新产品。 敏捷开发强调的最重要的一点就是“快”。 也就是要求通过快速迭代来获取频繁的客户反馈。 这就特别适合应对市…

Python教你如何让代码摆脱死循环的困扰!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在编写Python代码时&#xff0c;无限循环是一个常见的问题&#xff0c;可能导致程序陷入死循环&#xff0c;使得代码无法正常执行。这篇博客将介绍一些方法&#xff0c;帮助大家防止和处理无限循环&#xff0c;确…

ansible变量的使用

本章主要介绍playbook中的变量 自定义变量使用变量文件字典变量列表变量facts变量内置变量变量的过滤器 为了能够写出更实用的playbook&#xff0c;需要在playbook中使用变量。下面来讲解playbook 中常见的变量。本章实验都在/home/lduan/demo2下操作&#xff0c;先把 demo2目…