学习react-Provider解决props需要层层传递问题

1.组件数据传递问题

数据传递:A(顶级组件)-》B组件(子组件)、C组件(孙子组件)…很多组件
这样得通过props层层传递到下面的组件
还有另一种解决方法,即通过全局对象来解决,使用Provider可以解决数据层层传递和每个组件都要传props的问题;

2.props传递例子

学习react-环境&手脚架&页面&路由
在上一节的路由配置文件中,HomePage传递了name值

// Router.tsx
const routes: RouteObject[] = [{path: '/',element:<HomePage name={"test"} /> //<Navigate to='home/one' /> // 重定向},{path: 'login',element: <LoginPage name={"login"} />},// 未匹配到页面{path: '*',element: <NotFoundPage name={"notfound"} />}
]

在这一节中,创建MainPage,并在HomePage中引用

// MainMeta.tsx
export interface MainProp extends MetaProp{}export interface MainState extends MetaState{}
// MainPage.tsx
class MainPage extends Component<MainProp, MainState> {constructor(props: MainProp) {super(props);this.state = { count: 0 };}render() {const { name } = this.props; //解构赋值return <h1>Hello main page, {name}!</h1>;}}

MainPage在HomePage中引用,并用props继续给MainPage传递name值

// MainPage.tsx
class MainPage extends Component<MainProp, MainState> {constructor(props: MainProp) {super(props);this.state = { count: 0 };}render() {const { name } = this.props; //解构赋值return <h1>Hello main page, {name}!</h1>;}}

如下图props的name字段,值为test,一层层传递
props的name字段,值为test, 一层层传递

3.用全局对象context

1. state共同维护context(function模式)

首先创造Global.tsx和ConfigProvider.tsx

// Global.tsx
class Global {constructor() {}count = 0;name = 'react';loading = true;
}const globalStore = new Global();
export {globalStore};
// ConfigProvider.tsx
export const configContext = React.createContext<
{ global: Global; setGlobal: React.Dispatch<React.SetStateAction<Global>>;} | null >(null);export const useConfig= ()=>useContext(configContext)interface Props{children: React.ReactNode
}
export function ConfigProvider({ children}:Props) {const [global, setGlobal] = useState(globalStore);return (<configContext.Provider value={{global, setGlobal}}>{children}</configContext.Provider>)}

在index.tsx引入ConfigProvider

// index.tsx
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement
);
root.render(<React.StrictMode><HashRouter><ConfigProvider><App /></ConfigProvider></HashRouter></React.StrictMode>
);

创建ActionBar.tsx,并获取Provider Global存储的值,并在点击事件里面触发改变Global存储的值

// ActionBar.tsx
const ActionBar = () => {const config = useConfig()return (<div onClick={() => {config?.setGlobal({...config.global, name:"kk"})}}><h3>{config?.global.name}-test actionbar</h3></div>);
}export default ActionBar;

在MainPage.tsx里面引用ActionBar

// MainPage.tsx
class MainPage extends Component<MainProp, MainState> {constructor(props: MainProp) {super(props);this.state = { count: 0 };}render() {const { name } = this.props; //解构赋值return(<div><ActionBar/><h1>Hello main page, {name}! </h1></div>); }}

2. state共同维护context(class 模式)

首先创建Global.tsx和ThemeProvider.tsx

// Global.tsx
export class Global {constructor() {}type = "";count = 0;name = 'react';loading = true;
}const globalStore = new Global();
export {globalStore};
// ThemeProvider.tsx
export interface ThemeContextStore{global: Global; setGlobal: React.Dispatch<React.SetStateAction<Global>>;
}
export const ThemeContext = React.createContext< ThemeContextStore | null >(null);interface Props{children: React.ReactNode
}
export function ThemeProvider({ children}:Props) {const [global, setGlobal] = useState(globalStore);return (<ThemeContext.Provider value={{global, setGlobal}}>{children}</ThemeContext.Provider>)}

在index.tsx引入ThemeProvider

// index.tsx
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement
);
root.render(<React.StrictMode><HashRouter><ThemeProvider><App /></ThemeProvider></HashRouter></React.StrictMode>
);

在MainPage.tsx里面用consumer使用 context

class MainPage extends Component<MainProp, MainState> {static contextType=ThemeContextconstructor(props: MainProp) {super(props);this.state = { count: 0 };}render() {const { name } = this.props; //解构赋值return(<ThemeContext.Consumer>{(test)=>(<div onClick={()=>{ test?.setGlobal({...test?.global, name:"ok"})}}>{name}={test?.global.name}</div>)}</ThemeContext.Consumer>); }}export default MainPage;  

3.使用reducer 维护context

首先创建Global.tsx和Provider.tsx

// Global.tsx
export class Global {constructor() {}type = "";count = 0;name = 'react';loading = true;
}const globalStore = new Global();
export {globalStore};
// Provider.tsx
export const stores = {globalStore};
type Action = {type:'set'|'get',key:keyof Global,value:any
}type GlobalContext = {global:Globaldispatch:React.Dispatch<Action>
}export const storesContext = React.createContext<GlobalContext | null>(null);export const useGlobal = ():GlobalContext|null => React.useContext(storesContext);interface Props{children: React.ReactNode
}function globalReducer(global:Global, action:Action):Global {switch (action.type) {case 'get':{return global;}case 'set': {return {...global, [action.key]:action.value};}default: {throw Error('Unknown action: ' + action.type);}}
}export function StoresProvider({ children}:Props) {const [global, dispatch] = useReducer(globalReducer, globalStore);return (<storesContext.Provider value={{global, dispatch}}>{children}</storesContext.Provider>);}

在index.tsx引入Provider

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement
);
root.render(<React.StrictMode><HashRouter><StoresProvider><App /></StoresProvider></HashRouter></React.StrictMode>
);

创建TitleBar.tsx,并获取Provider Global存储的值,并在点击事件里面触发改变Global存储的值

// TitleBar.tsx
onst TitleBar = () => {const [name, setName] = useState("do");const globalContext = useGlobal ();return (<div onClick={() => {globalContext?.dispatch({type: 'set',key: "count",value:1});//setName("click")}}><h3>{globalContext?.global.count}- {name}</h3></div>);
}export default TitleBar;

在MainPage.tsx里面引入Titlebar

// MainPage.tsx
class MainPage extends Component<MainProp, MainState> {constructor(props: MainProp) {super(props);this.state = { count: 0 };}render() {const { name } = this.props; //解构赋值return(<div><TitleBar/><h1>Hello main page, {name}! </h1></div>); }

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

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

相关文章

搭建自己的金融数据源和量化分析平台(二):读取上交所股票列表

我在上交所没发现上交所有像深交所一样的一键下载股票xls文档的按钮&#xff0c;因此上交所的股票列表读取就会比较麻烦。总体思路是查出来所有股票的代码之后根据股票代码逐一发起HTTP请求读取公司英文名、总股本、流通股本等详细信息&#xff0c;这就导致上交所爬虫的网络交互…

堆的实现-适用于算法竞赛

首先讲一下能够实现的操作。 插入一个数查找最小值删除最小值删除任意一个元素修改任意一个元素 什么是堆&#xff1f; 堆其实是一棵完全二叉树。 即处理叶子节点和倒数第一层节点&#xff0c;其他节点都有两个子节点&#xff0c;而且顺序是从上到下&#xff0c;从左到右。 …

使用VMware安装Linux虚拟机

一、下载 通过百度网盘分享的文件&#xff1a;CentOS系统安装包 链接&#xff1a;https://pan.baidu.com/s/1_eqYl8HcNt2GcGDjgOElgg 提取码&#xff1a;cu07 二、安装 &#xff08;1&#xff09;双击打开软件 &#xff08;2&#xff09; 创建新的虚拟机 &#xff08;3&…

PyQt ERROR:ModuleNotFoundError: No module named ‘matplotlib‘

Solution:打开cmd输入指令下载malplotlib pip install matplotlib

Kubernetes:优势、场景与特点

Kubernetes:优势、场景与特点 1、优势2、适应场景3、特点💖The Begin💖点点关注,收藏不迷路💖 1、优势 容器编排:自动化管理容器生命周期,简化运维。轻量级开源:降低部署成本,易于集成到现有系统。弹性伸缩:根据业务负载自动调整资源,确保应用性能。负载均衡:高…

微软第四季度财报预览:增长动力追踪

微软公司即将在2024年7月30日&#xff08;周二&#xff09;美国市场收盘后发布第四季度财务结果。 微软的收益 - 预期如何 美股券商开户通道 市场预计&#xff0c;微软即将到来的2024年第四季度的收入将年增长14.5%&#xff0c;达到644亿美元&#xff0c;高于2023年第四季度…

linux添加普通用户后无法使用K8S的kubectl命令怎么办/Linux普通用户管理K8S/Linux下普通用户无法使用K8S命令

1.给Linux添加普通用户 sudo useradd mqq #添加mqq账号 sudo passwd mqq #给mqq账号设置密码&#xff0c;需要输入2次&#xff0c;我输入密码是Admin1232.利用mqq用户输入K8S命令报错 3.给mqq用户提权 suduers文件位于路径/etc/sudoers #编辑文件/etc/sudoers vim /etc/su…

Matlab编程资源库(10)离散傅立叶变换

一、离散傅立叶变换算法简要 给定一个N点的离散信号序列x(n)&#xff0c;其中n表示时刻&#xff0c;n 0, 1, 2, ..., N-1。 定义离散傅立叶变换的频域序列X(k)&#xff0c;其中k表示频率&#xff0c;k 0, 1, 2, ..., N-1。 通过以下公式计算每个频率对应的复数值&#xff…

Python实战:实现B-树

B-树是一种自平衡的树数据结构&#xff0c;广泛用于数据库和文件系统中&#xff0c;因为它能够维护排序数据并支持高效的插入、删除和查找操作。在本篇博客中&#xff0c;我们将探讨B-树的概念&#xff0c;并通过Python实现来加深理解。 什么是B-树&#xff1f; B-树是一种平…

03。正式拿捏ArkTS语言第一天

1, 打印日志命令 &#xff1a; console.log() 2, 三种基本数据类型&#xff1a; number 数字类型 &#xff08;数字&#xff09; string 字符串类型&#xff08;例如&#xff1a;“我是字符串”&#xff09; boolean 布尔类型 (true 或者 false) ***…

【C语言报错已解决】Use of Uninitialized Variable

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引言&#xff1a; 在编程中&#xff0c;未初始化的变量是一个常见的问题&#xff0c;它可能导致程序的行为变得不可预测。未初…

Matlab更换主题颜色附代码

解压后参考记录本教程 GitHub - scottclowe/matlab-schemer: Apply and save color schemes in MATLAB with ease. 本博客绑定了资源

【前端 08】简单学习js字符串

JavaScript中的String对象详解 在JavaScript中&#xff0c;字符串&#xff08;String&#xff09;是一种非常基础且常用的数据类型&#xff0c;用于表示文本数据。虽然JavaScript中的字符串是原始数据类型&#xff0c;但它们的行为类似于对象&#xff0c;因为JavaScript为字符…

windows 安装 Linux 子系统 Ubuntu,并编译安装nginx

1. 安装Ubuntu 首先可以在 Microsoft Store 自行搜索安装 Ubuntu&#xff0c;个人建议安装 22 版本的即可。Ubuntu安装完成后&#xff0c;以管理员身份打开CMD&#xff0c;运行如下命令&#xff1a; wsl --install 此时打开Ubuntu已经可以正常使用了。 2. 安装C/C编译器 对于…

java算法day25

java算法day25 广度优先搜索岛屿数量深搜岛屿数量广搜 广度优先搜索 核心&#xff1a;从起点出发&#xff0c;以起始点为中心一圈一圈进行搜索&#xff0c;一旦遇到终点&#xff0c;记录之前走过的节点就是一条最短路。搜索的方式是上下左右 一张图说明白模拟过程&#xff1…

【C语言】深入探讨数组传参

一、数组传参简介 在C语言中&#xff0c;数组传参是一个常见的操作&#xff0c;尤其是在处理大量数据或需要多次访问相同数据集时。理解如何传递数组以及这些方法之间的差异是编写高效和安全代码的关键。在这篇博客中&#xff0c;我们将详细讨论C语言中数组传参的几种常见方法&…

docker 构建 qemu

docker 编译 安装 qemu 安装依赖软件 apt-get install -y zlib1g-dev pkg-config libglib2.0-dev libmount-dev libpixman-1-dev apt-get install -y zlib1g-dev pkg-config libglib2.0-dev libmount-dev libpixman-1-devsudo apt-get install ptyhon3.7 sudo apt-get insta…

rhce THE homework of first

ssh远程免密登录成功 下载httpd和nginx 关闭防火墙 查看selinux的状态 为服务器配置ip 填充网站的内容 添加服务器配置

Python爬虫入门01:在Chrome浏览器轻松抓包

文章目录 爬虫基本概念爬虫定义爬虫工作原理爬虫流程爬虫类型爬虫面临的挑战 使用Chrome浏览器抓包查看网页HTML代码查看HTTP请求请求头&#xff08;Request Header&#xff09;服务器响应抓包的意义 爬虫基本概念 爬虫定义 爬虫&#xff08;Web Crawler 或 Spider&#xff0…

MongoDB教程(二十三):关于MongoDB自增机制

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、MongoD…