学习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,一经查实,立即删除!

相关文章

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

首先讲一下能够实现的操作。 插入一个数查找最小值删除最小值删除任意一个元素修改任意一个元素 什么是堆&#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

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

微软公司即将在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…

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语言中数组传参的几种常见方法&…

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…

数字孪生在奥运会上的应用

数字孪生是一种精确的虚拟空间表示&#xff0c;能够实时模拟场馆内的各种变化或场景。国际奥委会正在确定高价值的应用案例和技术要求&#xff0c;将应用案例分为六个主要领域&#xff1a;场馆规划、利益相关者支持与参与、操作准备、粉丝体验、遗产和运营效率。每个案例将基于…

【前端 13】Vue快速入门

Vue快速入门 在现代Web开发中&#xff0c;尽管通过HTML、CSS和JavaScript我们能够构建出美观且功能丰富的页面&#xff0c;但随着项目规模的增大&#xff0c;这种传统的开发方式在效率上逐渐显得力不从心。为了提高开发效率&#xff0c;前端开发者们引入了多种框架和库&#x…

MySQL环境的配置文件json

突然了解到&#xff0c;使用json文件去进行环境的配置&#xff0c;这样修改参数的时候就只需要去改json文件中的内容&#xff0c;不需要去修改代码中的内容&#xff0c;其他人的MySQL和我的MySQL也不同&#xff0c;这时其他人只需要修改json文件中的内容&#xff0c;清晰明了&a…

基于STC8H系列单片机的定时器系统

基于STC8H系列单片机的定时器系统 STC8H4K64TL单片机介绍STC8H4K64TL单片机管脚图&#xff08;48个引脚&#xff09;STC8H4K64TL单片机串口仿真与串口通信STC8H4K64TL单片机管脚图&#xff08;32个引脚&#xff09;STC8H4K64TL单片机管脚图&#xff08;20个引脚&#xff09;STC…