react传参有哪些常用方法?--Props,Context API和Redux全局管理

在 React 中,父子组件之间的传参主要通过以下几种方式实现:
             1) Props 传递:父子传参
             2)Context  API: 跨多层组件传递数据
             3) Redux: 全局状态管理库

一、Props父子组件传参(传值、传方法)

1. 父传子数据

// 父组件
<ChildComponent someProp={someValue} />
// 子组件
function ChildComponent(props) {
const { someProp } = props;  // 使用props获取父组件传的值
}

2.子传父 (回调函数)

 父组件将一个或多个回调函数作为 props 传递给子组件,子组件在需要时调用这些函数,将数据回传给父组件。

// 父组件
const handleData = (data) => {// 处理数据
};<ChildComponent onDataToParent={handleData} />// 子组件
function ChildComponent(props) {const { onDataToParent } = props;  // 使用props获取到父组件传过来的参数const sendData = (data) => {onDataToParent(data);  // 子组件调用父组件传过来的函数,回传给父组件};
}

3. 父子传参的demo

父组件:

import React from 'react';
import ChildComponent from './ChildComponent.tsx';function ParentComponent() {// 定义父组件的状态和处理函数const [childData, setChildData] = React.useState('Initial Data');// 定义一个处理函数,用于接收子组件传递的数据const handleDataFromChild = (newData) => {setChildData(newData);alert(`Data from child: ${newData}`);};return (<div><h1>Parent Component</h1><p>Current Data: {childData}</p>{/* 将数据和回调函数作为 props 传递给子组件 */}<ChildComponentchildData={childData}onDataToParent={handleDataFromChild}/></div>);
}export default ParentComponent;

子组件ChildComponent.tsx:

import React from 'react';function ChildComponent(props) {// 从 props 中解构出子组件接收到的数据和回调函数const { childData, onDataToParent } = props;// 定义一个函数,用于更新子组件的状态,并触发回调函数const updateData = () => {const newData = `Updated Data from Child: ${new Date().toLocaleTimeString()}`;onDataToParent(newData); // 调用父组件传递的回调函数};return (<div><h2>Child Component</h2><p>Received Data: {childData}</p>{/* 一个按钮,点击时调用 updateData 函数 */}<button onClick={updateData}>Send Data to Parent</button></div>);
}export default ChildComponent;

二、Context API

在react中使用Context API 可以轻松的在组件数间传递数据,无需听过每一层的手动传递props。

步骤 1: 创建 Context 

首先,使用 React.createContext 创建一个新的 Context 对象。

utils/context.js文件:

import React from 'react';const MyContext = React.createContext('default value');
export default MyContext;

步骤 2: 提供 Context 值

然后,在组件树的适当层级使用 <MyContext.Provider> 来包裹子组件,并通过 value 属性传递数据。


import React from 'react';
import MyContext from '../../utils/context.js';
import ChildComponent from './ChildComponent.jsx'function App() {const appData = { message: 'Hello, World!', number: 42 };return (<MyContext.Provider value={appData}><ChildComponent /></MyContext.Provider>);
}export default App;

在子组件ChildComponent.js中,使用 useContext Hook 来访问 Context 的值。


import React, { useContext } from 'react';
import MyContext from '../../utils/context.js';function ChildComponent() {const { message, number } = useContext(MyContext);  // 接受传参的值return (<div><p>{message}</p><p>{number}</p></div>);
}export default ChildComponent;

附加功能:动态 Context 值

如果你需要在应用中动态更改 Context 的值,可以在 Provider 中使用状态来实现。

// App.js
import React, { useState } from 'react';
import MyContext from '../../utils/context.js';
import ChildComponent from './ChildComponent.tsx';export default function App() {const [appData, setAppData] = useState({ message: 'Hello, World!', number: 42 });const updateMessage = (newMessage, newNum) => {setAppData((prev) => ({ ...prev, message: newMessage, number: newNum }));};return (<MyContext.Provider value={{ ...appData, updateMessage }}><ChildComponent /></MyContext.Provider>);
}

在子组件ChildComponent.tsx中,你可以使用提供的函数来更新 Context 的值。

// ChildComponent.js
import React, { useContext } from 'react';
import MyContext from '../../utils/context.js';export default function ChildComponent() {const { message, number, updateMessage } = useContext(MyContext);const handleClick = () => {updateMessage('New message from child!', 3333);};return (<div><p>{message}</p><p>{number}</p><button onClick={handleClick}>Update Message</button></div>);
}

三、Redux  全局状态管理

1. redux是什么?

1、redux是一个专门用于做状态管理的js库(不是react插件库)。
2、它可以用在react,angular,vue等项目中,但基本与react配合使用。
3、作用:集中式管理react应用中多个组件共享的状态。
4、 redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写

 2. 什么情况下需要使用redux

1、某个组件的状态,需要让其他组件可以随时拿到(共享)。
2、一个组件需要改变另一个组件的状态(通信)。
3、总体原则:能不用就不用,如果不用比较吃力才考虑使用。

3. 核心概念

1、Store

store : 用于存储共享数据的仓库

2、State

 State 是只读的,任何修改都必须通过触发 actions 来完成。

3、 Action

action : store中所有数据的变化,必须通过派发(dispatch)action来更新
action是一个普通的JavaScript对象,用来描述这次更新的type和content 

4、Reducer

reducer : reducer是一个纯函数,接收当前状态和 action,返回新的状态,将state和action联系在一起
reducer做的事情就是将传入的state和action结合起来生成一个新的state 

4.工作原理

Redux 的工作流程遵循单向数据流原则:

  1. View 发起 Action

    • 用户与界面交互,触发一个 Action。
  2. Dispatch Action

    • Action 被发送到 Store。
  3. Reducer 处理 Action

    • Store 调用 Reducer,传入当前 State 和 Action,Reducer 返回新的 State。
  4. State 更新

    • Store 更新 State,任何订阅了 Store 的组件都会收到通知并重新渲染。
  5. View 更新

    • 组件从 Store 中读取新的状态,并更新 UI。

5. demo示例

安装redux:

npm install redux

 stoer/index.ts 文件

import { createStore, combineReducers } from "redux";
// import UserReducer from "./user/reducer.ts";
import todoReducer from './todo/todoReducer.ts'; //
const reducer = combineReducers({// user: UserReducer,todos: todoReducer,
});// 创建数据公共的存储区域
const store = createStore(reducer,  // 辅助管理数据,reducer是一个纯函数,不需要直接修改state
);export default store;

store/todo/action.ts

// 定义action类型
export const ADD_TODO = 'ADD_TODO';
export const DELETE_TODO = 'DELETE_TODO';
export const TOGGLE_TODO = 'TOGGLE_TODO';// 定义action creators
export const addTodo = (text) => ({type: ADD_TODO,payload: {id: new Date().getTime(),text,completed: false,},
});export const deleteTodo = (id) => ({type: DELETE_TODO,payload: { id },
});export const toggleTodo = (id) => ({type: TOGGLE_TODO,payload: { id },
});

store/todo/todoReducer.ts

import { ADD_TODO, DELETE_TODO, TOGGLE_TODO } from './action.ts';// 定义初始状态
const initialState = [];// 定义reducer函数
const todoReducer = (state = initialState, action) => {switch (action.type) {case ADD_TODO:return [...state, action.payload];case DELETE_TODO:return state.filter(todo => todo.id !== action.payload.id);case TOGGLE_TODO:return state.map(todo => {if (todo.id === action.payload.id) {return { ...todo, completed: !todo.completed };}return todo;});default:return state;}
};export default todoReducer;

页面使用

pages/reducer/index.tsx

import React from 'react';
import { Button, message } from 'antd';
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, deleteTodo, toggleTodo } from '../../store/todo/action.ts';const TodoListStyles = {container: {padding: '20px',},todoItem: {listStyleType: 'none',marginBottom: '10px',},
};function TodoList() {// useSelector Hook,用于从 Redux store 中选择数据。接收一个函数作为参数// 使用 useSelector 钩子从 Redux store 获取 todos 状态const todos = useSelector((state) => state.todos);const dispatch = useDispatch();// 添加待办事项const handleAddTodo = () => {const text = prompt('请输入Todo项的内容:');if (text) {dispatch(addTodo(text));}};// 删除待办事项const handleDeleteTodo = (id) => {dispatch(deleteTodo(id));};// 切换待办事项的完成状态const handleToggleTodo = (id) => {dispatch(toggleTodo(id));};return (<div style={TodoListStyles.container}><h2>Todo List</h2><ul>{todos.map((todo) => (<li key={todo.id} style={TodoListStyles.todoItem}><spanstyle={{textDecoration: todo.completed ? 'line-through' : 'none',cursor: 'pointer',}}onClick={() => handleToggleTodo(todo.id)}>{todo.text}</span><Buttontype="link"dangerstyle={{ marginLeft: '10px' }}onClick={() => handleDeleteTodo(todo.id)}>删除</Button></li>))}</ul><Button onClick={handleAddTodo}>添加Todo</Button></div>);
}export default TodoList;

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

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

相关文章

基于Django的博客系统之增加手机验证码登录(九)

需求文档 概述 实现基于Redis和第三方短信服务商的短信验证码登录功能。用户可以通过手机号码获取验证码&#xff0c;并使用验证码进行登录。 需求细节 用户请求验证码 用户在登录页面输入手机号码并请求获取验证码。系统生成验证码并将其存储在Redis中&#xff0c;同时通过…

【Android】安卓开发的前景

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

VMware虚拟机-Ubuntu设置共享文件夹(超详细)

目录 前言1. 其他教程2. 创建共享文件夹3. VMware 设置4. Ubuntu 设置4.1 创建 hgfs 目录:4.2 挂载共享目录4.3 验证是否挂载成功4.4 设置开机自动挂载创作不易,禁止转载抄袭!!!违者必究!!! 创作不易,禁止转载抄袭!!!违者必究!!! 创作不易,禁止转载抄袭!!!违…

韩顺平0基础学java——第24天

p484-508 System类 常见方法 System.arrycopy&#xff08;src&#xff0c;0&#xff0c;dest&#xff0c;1,2&#xff09;&#xff1b; 表示从scr的第0个位置拷贝2个&#xff0c;放到目标数组索引为1的地方。 BigInteger和BigDecimal类 保存大整数和高精度浮点数 BigInte…

Springboot 整合 Flowable(一):使用 flowable-UI 绘制流程图

目录 一、Flowable简介 二、Flowable 与 Activiti 的区别 三、流程图的绘制&#xff08;以员工请假流程图为例&#xff09; 1、下载 flowable 的压缩包&#xff1a; 2、启动包中的 tomcat 3、登录页面 4、绘制结束&#xff0c;导出 bpmn20.xml文件 一、Flowable简介 Fl…

老胡的周刊(第146期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 pingvin-share[2] Pingvin Share 是一个可自…

【机器学习】图神经网络:深度解析图神经网络的基本构成和原理以及关键技术

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言一、图数据及其应用场景1.1 图数据的定义和特征1.2 常见的图数据结构1.2.1 社交网络1.2.2 知识图谱1.2.3 分子结构1.2.4 交通网络 1.3 图数据在不同领域的应用实例1.3.1 社交网络中的推荐系统1.3.2 知识图谱中的信息检索…

StarRocks详解

什么是StarRocks&#xff1f; StarRocks是新一代极速全场景MPP数据库&#xff08;高并发数据库&#xff09;。 StarRocks充分吸收关系型OLAP数据库和分布式存储系统在大数据时代的优秀研究成果。 1.可以在Spark和Flink里面处理数据&#xff0c;然后将处理完的数据写到StarRo…

SQL 表连接(表关联)

目录 一、INNER JOIN&#xff08;内连接,等值连接&#xff09; 二、LEFT JOIN&#xff08;左连接&#xff09; 三、RIGHT JOIN&#xff08;右连接&#xff09;&#xff1a; 一、INNER JOIN&#xff08;内连接,等值连接&#xff09; 用途&#xff1a;获取两个表中字段能匹配上…

如何解决 Git 默认不区分文件名大小写和同名文件共存?

修改文件命名的大小写&#xff0c;不会有 git 记录 本文章的例子&#xff1a;将 demo.vue 文件命名改为 Demo.vue 1、在Git项目路径下执行该命令 git config core.ignorecase false &#xff08;1&#xff09;以上方法可以实现 git 区分 demo.vue 与 Demo.vue 文件&#xff0…

功能强大的多功能文档转换工具Neevia Document Converter Pro 7.5.0.241

Neevia Document Converter Pro是一款功能强大的Windows软件,旨在将文档转换为各种格式,包括PDF、TIFF、JPEG和许多其他格式。该程序专为在企业环境中使用而设计,提供文档转换和处理过程的自动化,这使其成为处理大量文档的组织的***工具。 Neevia Document Converter Pro的…

Oracle的listagg的用法和例子

LISTAGG 是 Oracle 数据库中用于将多行数据连接&#xff08;聚合&#xff09;成单个字符串的函数。它通常与 GROUP BY 子句一起使用&#xff0c;以便将来自多个行的值连接成一个由指定分隔符分隔的字符串。 语法 sql LISTAGG(column_value, delimiter) WITHIN GROUP (ORDER …

PHP7 数组的实现

前提 PHP版本&#xff1a;php7.0.29使用到的文件 php-src/Zend/zend_types.hphp-src/Zend/zend_hash.hphp-src/Zend/zend_hash.cphp-src/Zend/zend_string.h 本文 是《PHP7底层设计和源码实现》第5章 数组的实现&#xff0c;学习笔记 功能分析 整体结构 bucket 里面增加h字段…

5、存储管理

磁盘分区方式 MBR格式 分区命令&#xff1a;fdisk 一共有14个分区&#xff08;4个主分区&#xff0c;扩展分区&#xff0c;逻辑分区&#xff09; MBR要求硬盘空间是小于2TB的 一块硬盘最多有4个主分区 GPT格式 分区命令&#xff1a;gdisk 一共可以有128个主分区 对硬盘大小没有…

CAD关于Curve偏移生成一个DBObjectCollection对象

关于Curve对象使用GetOffsetCurves(double)生成一个DBObjectCollection 对象 很奇怪&#xff0c;为什么是一个集合的对象&#xff0c;今天试了一下&#xff0c;生成的确实只得到一个偏移对象的实体。只需要提取第一个索引值即可。 //获得偏移的实体using (Transaction trans …

欣九康诊疗系统助力诊所向数字化转型

数字化已经成为各行各业转型的重点方向&#xff0c;而为了不被时代所淘汰&#xff0c;医疗机构也势必要紧跟潮流&#xff0c;本人作为门诊部的负责人深知医疗机构要想实现数字化转型那么拥有一款便捷实用的医疗平台是必不可少的&#xff0c;近几年&#xff0c;随着国家大力支持…

动态 SQL

动态 SQL 是 MyBatis 的强大特性之一&#xff0c;能够完成不同条件下不同的 sql 拼接。也就是说执行的 SQL 语句并不是固定的&#xff0c;而是不同人的不同操作执行的语句会有所差异。MyBatis 通过使用 标签 的方式来实现这种灵活性的。 <if>标签 例如在有一些网站进行…

【可控图像生成系列论文(一)】MimicBrush 港大、阿里、蚂蚁集团合作论文解读

背景&#xff1a;考虑到用户的不同需求&#xff0c;图像编辑是一项实用而富有挑战性的任务&#xff0c;其中最困难的部分之一是准确描述编辑后的图像应该是什么样子。 创新点&#xff1a;在本文作者提出了一种新的编辑形式&#xff0c;称为模仿编辑&#xff0c;以帮助用户更方…

开放式耳机哪个品牌质量比较好?2024高性价比机型推荐!

随着音乐技术的不断进步&#xff0c;耳机也必不可少&#xff0c;开放式耳机成为一部分音乐发烧友们的选择。从最初的简单音质系统&#xff0c;到如今的高清解析&#xff0c;开放式耳机也在不断升级。音质也能够和入耳式一样纯净自然&#xff0c;佩戴舒适&#xff0c;无论是街头…

使用同步和异步方式更新插入MongoDB数据的性能对比

在这篇文章中&#xff0c;我将探讨如何使用同步和异步方式插入数据到MongoDB&#xff0c;并对两种方式的性能进行对比。并将通过Python中的 pymongo 和 motor 库分别实现同步和异步的数据插入&#xff0c;并进行测试和分析。 项目结构 MongoDB 连接设置&#xff1a;设置Mongo…