让我带你迅速吃透React组件通信:从入门到精通(上篇)

我们为什么说组件通信是 React 的核心

  1. React 这门框架的核心是组件化,任何一个完整的 React 应用,都是由多个独立组件协同工作构成的,组件之间的协同,其本质就是数据传递,共享与同步 ,这也就是我们常说的 组件通信
  2. React严格遵循单向数据流原则:数据只能自上而下从父组件传递到子组件,状态的修改只能由持有该状态的组件完成。

在本文中,我将从基础到高阶再讲到一些特殊场景,来聊一聊 React 组件间通信的所有方案,可供新手入门及老手查缺补漏 (本文我所使用的技术栈为 React19 + 函数组件 + Hooks

一、基础入门篇 父子组件间的通信 (为 React 中最常用的一种方式)

父子组件是 React 中最常见的组件关系,所有通信方式的底层逻辑,都基于父子通信的规则延伸而来

1.1 父向子传值

实现原理: 父组件直接在子组件的标签上绑定属性值,子组件通过参数props接受 ,此时该数据在子组件中仅为可读状态,不可修改,但该数据状态对象的属性值可以进行修改

代码实现:

若子组件直接修改父组件传递的状态对象,会报错

父向子传值的使用场景:

  1. 适用于所有父子组件之间的数据传递,是 React 组件通信的第一选择
  2. 当子组件的渲染内容完全由父组件决定时
  3. 当需要父组件向子组件传递事件处理函数

父子组件传值注意点:

  1. 禁止直接修改props,props是只读的,直接修改对象/数组类型的props,会破坏单向数据流,且不会触发组件重新渲染
  2. 需要避免透传地狱:不要为了给孙组件传值,让中间所有层级的组件都接力传递props,后文我会讲解解决方案
  3. 引用类型 props 注意重新渲染: 如果 props 传递的是对象/数组/函数,父组件每次重新渲染都会生成新的引用,导致子组件不必要的重新渲染,可以通过使用useMemo/useCallback优化

1.2 子向父传值 (通过回调函数使子组件与父组件同步)

实现原理:利用 props 可以传递函数的特点,父组件可以通过将状态修改函数把 props 传递给子组件,而子组件触发该函数并传入参数,可实现子组件向父组件同步数据,但其本质仍为单向数据流的延伸

代码实现:

----------------通过简单的子向父传值实现通过改变子组件来改变父组件的内容---------------

子向父传值的使用场景:

  1. 当子组件需要向父组件传递事件触发信息时
  2. 当子组件需要修改父组件的状态时
  3. 当需要实现表单类子组件的输入值同步时

父子组件传值需要注意的点

  1. 闭包陷阱:回调函数中如果依赖父组件的状态,则需要注意闭包问题,可通过 useCallback + 正确的依赖数组来解决 (具体解决方法将在后续更新文章中提到)

2.避免频繁触发回调:例如当使用onChange实时触发回调时,可能会导致父组件频繁重渲染,可以通过添加防抖来优化性能 3. 不要在子组件内修改回调函数的返回值: 为了保持单向数据流,请让子组件只负责触发回调,而不处理状态的修改逻辑,以便增加代码的可读性

1.3 父子直接通信:Ref 转发

实现原理:

  1. 让子组件"打开后门" :使用 forwardRef 把父组件的 ref 传进来

  2. 子组件"提供菜单" :用 useImperativeHandle 告诉父组件 :"你可以调用我的这几个方法"

  3. 父组件"发号施令" : 通过 ref.current.方法名() 直接调用

代码实现:

让我通过实现点击父组件内的一个按钮,使得子组件内的输入框自动聚焦,并获得子组件输入框内的值这一功能来体现该方法的作用

父子直接通信的使用场景:

例如:

  1. 在父组件里有一个按钮,点击后,想要直接命令子组件的输入框"自动聚焦",或者让子组件里的弹窗"打开" 此时使用 props 便有些别扭 (此时父组件不需要给子组件传递数据,只是想"命令"它一下),此时便可使用 Ref + useImperativeHandle使父组件能够直接调用子组件内部的某些方法
  2. 控制DOM元素的行为:如聚焦,播放视频,滚动到某个位置
  3. 控制子组件的状态切换:如打开/关闭弹窗,展开/收起折叠面板

父子直接通信需要注意的点:

  1. 尽量不用,优先使用props和回调函数
  2. 若不使用 useImperativeHandle 则父组件能通过 ref 拿到子组件所有的东西,这是一个很危险的行为

结语

基于篇幅限制,本文需要让我们分为上中下上篇

传送门:让我带你迅速吃透React组件通信:从入门到精通(中篇)

传送门:让我带你迅速吃透React组件通信:从入门到精通(下篇)

相关推荐
小星哥哥2 小时前
JavaScript 动态导入 (Dynamic Imports)
javascript
阿懂在掘金2 小时前
Vue 表单避坑(一):为什么 v-model 绑定对象属性会偷偷修改父组件数据?
前端·vue.js
小码哥_常2 小时前
Android与JS交互:解锁混合开发的魔法之门
前端
leafyyuki2 小时前
如何优雅地上传大文件?分片上传实战指南
前端·音视频开发
Mintopia2 小时前
现代 Vue 3 页面组件文件安排与通信实践
前端
只会cv的前端攻城狮2 小时前
兼容性地狱-Uniapp钉钉小程序环境隔离踩坑实录
前端·uni-app
流水白开2 小时前
前端设计模式
javascript·面试
赵_叶紫2 小时前
Node.js 知识点梳理与实战代码
前端
颜酱2 小时前
从0到1实现LRU缓存:思路拆解+代码落地
javascript·后端·算法