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

React中子传父的方式及原理

方式挺多的,先说最常用的通过props进行父子组件的数据传递和修改以及原理

在React中,props不仅用于传递数据,它们也可以传递可以执行的函数,这使得子组件能够间接更新父组件的状态。这种方法强化了React的单向数据流策略,即数据总是从上向下(从父组件到子组件)流动。

实例分析

考虑一个场景,我们有一个父组件ParentComponent管理一个文本状态,和一个子组件ChildComponent展示一个按钮,当按钮被点击时更新父组件的状态。

function ParentComponent() {const [text, setText] = useState('初始文本');const handleTextChange = newText => {setText(newText);};return <ChildComponent onTextChange={handleTextChange} />;
}
function ChildComponent({ onTextChange }) {return <button onClick={() => onTextChange('更新后的文本')}>点击我</button>;
}

这里,ChildComponent通过点击按钮调用onTextChange,这实际上触发了ParentComponent中的handleTextChange方法,从而更新了父组件的状态。


原理分析:

在React中,子组件可以通过调用父组件传递给它的函数来影响父组件的状态。这个过程主要涉及到两个重要的JavaScript和React的概念:函数作为一等公民闭包

函数作为一等公民

在JavaScript中,函数可以像任何其他变量一样被传递和赋值。因此,在React中,你可以把一个函数作为prop从父组件传递给子组件。子组件接收到这个函数后,可以在适当的时候调用它。

闭包

当父组件中的函数被定义时,它能够“记住”并访问它被创建时所在的环境中的变量。即使这个函数被传递到另一个组件中去执行,它仍然能够访问原来的环境中的变量。这就是闭包的作用。

使用步骤

  1. 在父组件中定义函数:你在父组件中创建一个函数,比如 handleDataChange。这个函数能够更新父组件的状态。
  2. 将函数传递给子组件:通过props,这个函数被传递到子组件。
  3. 子组件调用这个函数:在子组件中,当某个事件发生(比如按钮点击),子组件就调用这个函数。

实例

假设你有一个按钮在子组件中,当按钮被点击,子组件调用从父组件接收到的函数:

function ChildComponent({ onDataChange }) {return <button onClick={() => onDataChange('new data')}>Change Data</button>;
}

这里的 onDataChange 函数实际上是父组件中的 handleDataChange 函数,当点击按钮时,这个函数被调用,参数 'new data' 被传递回父组件。

function ParentComponent() {const [data, setData] = useState('Initial data');const handleDataChange = newData => {setData(newData);};return <ChildComponent onDataChange={handleDataChange} />;
}

在这个例子中,handleDataChange 更新了父组件的状态。尽管这个函数在子组件中被调用,但因为JavaScript的闭包特性,它仍可以访问和修改父组件的状态。


其他的方式

在 React 中,除了通过 props 传递回调函数来让子组件影响父组件的状态之外,还有几种其他的方法可以实现组件间的状态管理和通信。这些方法各有适用场景,可以根据应用的复杂度和需求选择最合适的一种。以下是一些常见的方法:

1. Context API

React 的 Context API 允许你在组件树中直接传递数据,而无需手动在每个层级传递 props。这对于要在许多不同层级的组件间共享数据的情况非常有用,如用户认证状态、主题设置等。

使用示例:

const MyContext = React.createContext();function ParentComponent() {const [value, setValue] = useState("initial");return (<MyContext.Provider value={{ value, setValue }}><ChildComponent /></MyContext.Provider>);
}function ChildComponent() {const { setValue } = useContext(MyContext);return (<button onClick={() => setValue("updated from child")}>Update Value</button>);
}

这里,ChildComponent 可以通过 useContext 钩子直接访问到由 ParentComponent 提供的 setValue 函数,并使用它来更新状态。

2. Redux

Redux 是一个用于管理应用状态的库,它提供了一个中央状态容器,允许你在应用的任何地方访问和修改状态。这在大型应用或多个组件需要访问同一状态时非常有用。

使用示例:

import { createStore } from 'redux';function reducer(state = { value: "initial" }, action) {switch (action.type) {case "UPDATE_VALUE":return { ...state, value: action.value };default:return state;}
}const store = createStore(reducer);function ParentComponent() {const value = store.getState().value;return (<div><ChildComponent /><p>{value}</p></div>);
}function ChildComponent() {return (<button onClick={() => store.dispatch({ type: "UPDATE_VALUE", value: "updated from child" })}>Update Value</button>);
}

在这个例子中,ChildComponent 使用 Redux store 发送一个 action 来更新全局状态,ParentComponent 显示这个状态。

3. React Hooks:useState, useReducer

对于更简单的场景,React 的内建钩子 useStateuseReducer 提供了轻量级的状态管理能力,这对于独立组件或小型应用是足够的。

使用 useReducer 示例:

function ParentComponent() {const [state, dispatch] = useReducer(reducer, { value: "initial" });return (<div><ChildComponent dispatch={dispatch} /><p>{state.value}</p></div>);
}function ChildComponent({ dispatch }) {return (<button onClick={() => dispatch({ type: "UPDATE_VALUE", value: "updated from child" })}>Update Value</button>);
}

这里,useReducer 提供了一种更灵活的方式来处理复杂的状态逻辑,而不必使用外部的状态管理库。


日常开发中使用频率高低排名

props这种不用说,是最高的,我们看其他几种方式

1. React内建的Hooks(useState, useReducer)

常用性: 非常高
适用场景:

  • 小到中型的应用
  • 组件内部状态管理
  • 简单的父子组件通信

Hooks 提供了一种轻量级的方式来管理组件的状态,是React官方推荐的状态管理方式。特别是useStateuseReducer,它们适用于大多数日常开发需求,简化了状态逻辑并减少了额外依赖。

2. Context API

常用性:
适用场景:

  • 需要在多个组件间共享状态时
  • 避免多层级prop透传的场景
  • 主题切换、用户偏好设置、权限管理等

Context API 提供了一种在组件树中传递数据的方法,无需通过每个层级显式传递props。这使得它成为管理全局数据(如用户认证信息、主题设置)的理想选择。

3. Redux

常用性: 中到高
适用场景:

  • 大型应用
  • 复杂的状态逻辑,多个组件需要访问相同的状态
  • 强大的调试工具和中间件支持需求

Redux 是一个独立于React的库,但在React社区中非常流行,尤其适用于大型或高度复杂的应用。它提供了严格的状态管理模式和强大的开发工具,如Redux DevTools。

4. MobX

常用性:
适用场景:

  • 中到大型应用
  • 更自然的响应式编程模型
  • 简化状态管理,自动追踪状态变化

MobX 提供了另一种状态管理方式,它通过透明的函数响应式编程(FRP)使状态管理变得直观和自动化。对于需要简单、高效状态同步的应用,MobX是一个很好的选择。

总结

选择哪种状态管理技术取决于多种因素:

  • 应用大小和复杂度:小型应用可能只需useStateuseReducer,而大型应用可能更适合使用Redux或MobX。
  • 团队熟悉度:选择团队成员熟悉的技术可以加快开发速度和降低学习成本。
  • 特定需求:如需要时间旅行调试、中间件或特殊的响应式需求等。

相关文章:

React中子传父的方式及原理

方式挺多的&#xff0c;先说最常用的通过props进行父子组件的数据传递和修改以及原理 在React中&#xff0c;props不仅用于传递数据&#xff0c;它们也可以传递可以执行的函数&#xff0c;这使得子组件能够间接更新父组件的状态。这种方法强化了React的单向数据流策略&#xf…...

【数据结构与算法】贪心算法及例题

目录 贪心算法例题一&#xff1a;找零问题例题二&#xff1a;走廊搬运物品最优方案问题输入样例例题三&#xff1a;贪心自助餐 贪心算法 贪心算法是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;以期望最终达到全局最优解的算法。它的核心思想是每次都选择当前最…...

【Origin+Python】使用External Python批量出图代码参考

目录 基本介绍环境配置官方代码示例基础代码详解我的代码效果视频进阶代码及去水印 基本介绍 origin2021后可以使用python实现批量绘图&#xff0c;一共有两种方式&#xff1a;一种是嵌入式Python&#xff0c;一种是外部Python访问Origin。详细介绍可以自己去查看&#xff0c;打…...

YOLOv8最新改进系列:融合DySample超轻量动态上采样算子,低延迟、高性能,目前最新上采样方法!!!遥遥领先!

YOLOv8最新改进系列&#xff1a;融合DySample超轻量动态上采样算子&#xff0c;低延迟、高性能&#xff0c;目前最新上采样方法&#xff01;&#xff01;&#xff01;遥遥领先&#xff01; DySample超轻量动态上采样算子全文戳这&#xff01;here! 详细的改进教程以及源码&am…...

ChatGPT基础(二) ChatGPT的使用和调优

文章目录 ChatGPT的特性采用关键词进行提问给ChatGPT指定身份提升问答质量的策略1.表述方式上的优化2.用"继续"输出长内容3.营造场景4.由浅入深&#xff0c;提升问题质量5.预设回答框架和风格 ChatGPT的特性 1.能够联系上下文进行回答 ChatGPT回答问题是有上下文的&…...

麒麟 V10 离线 安装 k8s 和kuboard

目录 安装文件准备 主机准备 主机配置 修改主机名&#xff08;三个节点分别执行&#xff09; 配置hosts&#xff08;所有节点&#xff09; 关闭防火墙、selinux、swap、dnsmasq(所有节点) 安装依赖包&#xff08;所有节点&#xff09; 系统参数设置(所有节点) 时间同步…...

PlayerSettings.WebGL.emscriptenArgs设置无效的问题

1&#xff09;PlayerSettings.WebGL.emscriptenArgs设置无效的问题 2&#xff09;多个小资源包合并为大资源包的疑问 3&#xff09;AssetBundle在移动设备上丢失 4&#xff09;Unity云渲染插件RenderStreaming&#xff0c;如何实现多用户分别有独立的操作 这是第381篇UWA技术知…...

项目管理工具——使用甘特图制定项目计划的详细步骤

甘特图是一种直观的项目管理工具&#xff0c;它有助于我们清晰地展示任务安排、时间管理和项目的进度。以下是使用甘特图制定项目计划的详细步骤&#xff1a; 1、创建项目&#xff1a;首先&#xff0c;在进度猫中创建新的项目&#xff0c;并设置项目的时间、工作日等参数。根据…...

python读取文件数据写入到数据库中,并反向从数据库读取保存到本地

学python&#xff0c;操作数据库是必不可少的&#xff0c;不光要会写python代码&#xff0c;还要会写SQL语句&#xff0c;本篇文章主要讲如何把本地txt文件中的数据读取出来并写入到对应的数据库中&#xff0c;同时将数据库单个表中的数据读出来保存在本地txt文件中。 话不多说…...

社交媒体数据恢复:Viber

Viber是一款流行的即时通讯应用&#xff0c;用于发送消息、语音通话和视频通话。然而&#xff0c;有时候我们会不小心删除一些重要的Viber聊天记录&#xff0c;这时候就需要进行数据恢复。本文将介绍如何在安卓设备上进行Viber数据恢复。 一、使用安卓数据恢复软件 安卓数据恢…...

蓝桥杯赛事介绍

蓝桥杯是由工业和信息化部人才交流中心主办的全国性IT学科赛事&#xff0c;全称为“蓝桥杯全国软件和信息技术专业人才大赛”。该赛事旨在推动软件和信息领域专业技术人才培养&#xff0c;提升大学生的创新能力和就业竞争力&#xff0c;为行业输送具有创新能力和实践能力的高端…...

TypeScript系列之-深度理解基本类型画图讲解

JS的类型(8)&#xff1a; null undefined string number boolean bigint symbol object&#xff08;含 Array, Function,Date.....&#xff09; TS的类型(87): 以上所有&#xff0c;加上 void, never, enum, unknown, any 再加上自定义类型 type interface 上一节我们说…...

Debian

使用root用户操作 直接使用su命令进行切换。 配置用户使用sudo命令 在安装好系统之后&#xff0c;使用用户名登录之后。需要执行需要root权限的命令&#xff0c;会发现无法执行成功。原因是没有配置用户使用sudo的权限。 编辑bash /etc/sudoers文件 可以先切换root用户安装…...

怎么使用JMeter进行性能测试?

一、简介 JMeter是Apache软件基金会下的一款开源的性能测试工具&#xff0c;完全由Java开发。它专注于对我们应用程序进行负载测试和性能测量&#xff0c;最初设计用于web应用程序&#xff0c;现在已经扩展到其他测试功能&#xff0c;比如&#xff1a;FTP、Database和LDAP等。…...

MySQL:锁的分类

文章目录 行级锁Record LockGap LockNext-Key Lock插入意向锁 表级锁表锁元数据锁&#xff08;MDL&#xff09;意向锁AUTO-INC 锁 全局锁 行级锁 Record Lock 记录锁有S锁&#xff08;共享锁/读锁&#xff09;和X锁&#xff08;排他锁/写锁&#xff09;之分&#xff0c;加完S…...

基于springboot实现房屋租赁管理系统设计项目【项目源码+论文说明】

基于springboot实现房屋租赁管理系统设计演示 摘要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对房屋租赁信息管理混乱&…...

揭秘Redis底层:一窥数据结构的奥秘与魅力

一、引言 Redis&#xff0c;以其高性能、高可靠、丰富的数据结构等特点&#xff0c;成为现代应用程序中不可或缺的缓存与存储组件。然而&#xff0c;Redis之所以能够实现如此卓越的性能&#xff0c;离不开其底层精巧的数据结构设计。本文将深入浅出地解析Redis底层五大核心数据…...

【网站项目】智能停车场管理系统小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…...

芒果YOLOv5改进94:检测头篇DynamicHead为目标检测统一检测头:即插即用|DynamicHead检测头,尺度感知、空间感知、任务感知

该专栏完整目录链接: 芒果YOLOv5深度改进教程 该创新点:在原始的Dynamic Head的基础上,对核心部位进行了二次的改进,在 原论文 《尺度感知、空间感知、任务感知》 的基础上,在 通道感知 的层级上进行了增强,关注每个像素点的比重。 在自己的数据集上改进,有效涨点就可以…...

获奖名单出炉,OurBMC开源大赛总决赛圆满落幕

4 月 12 日&#xff0c;由开放原子开源基金会牵头、OurBMC 社区及理事长单位飞腾信息技术有限公司联合承办的 OurBMC 开源大赛总决赛在江苏宿迁圆满落幕。共有 10 支参赛队伍凭着初赛的优异表现进入决赛&#xff0c;在路演现场上演了一场精彩绝伦的对决。 江苏省工信厅软件和信…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...