现代 React Web 开发实战
宋一玮
FreeWheel 中国研发中心前端架构师
16115 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
现代 React Web 开发实战
15
15
1.0x
00:00/00:00
登录|注册

12|组件表与里(上):数据是如何在 React 组件之间流转的?

你好,我是宋一玮,欢迎回到 React 应用开发的学习。
上节课我们学习了 React 的事件处理,理解了 React 事件是标准化封装过的合成事件。在这基础之上,还学习了受控组件和事件冒泡 / 捕获的概念,并为 oh-my-kanban 项目加入了实用的卡片拖拽功能。其间我们也不忘与浏览器原生 DOM 事件作对比。
到目前为止,包括生命周期、Hooks、事件处理,你已经基本了解了可以在哪些位置编写组件逻辑代码。那么当你在 React 应用中写了多段逻辑代码后,代码之间是怎么串联起来的?反过来说,怎样才能把每段代码写在它合适的地方,让它们各司其职,支撑应用跑起来呢?
接下来我们会用两节课的时间,把视野从单个 React 组件中拓展开来,看看组件与组件之间的分工和交互,从而帮助你解决刚才提出的问题。
我把这两节课分别称为组件的“面子”和“里子”。这节课的重点,是 React 的单向数据流。当你理解了在 React 的设计哲学中数据应该如何流转,就会对如何设计 props 和 state 了然于心。
在学习概念的基础上,也请你跟随我,从数据流的视角重新梳理早在第 5 节课就基本定型的 oh-my-kanban 各组件,进行一次大重构:对组件文件进行拆分,并根据需要调整各组件的 props 和 state。同时我们也会学习 React 另一个与数据流相关的概念——context。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了React组件之间的数据流转,重点讲解了React的单向数据流特点。首先,作者解释了React数据流包含的三种数据:属性props、状态state和上下文context,并重点讲解了props的使用和赋值方式。此外,还介绍了props的单向数据流特点,即只能从父组件流向子组件,不能反向流动。在后半部分,文章详细介绍了React中的state和context的使用方法,以及它们的数据流向。通过示例代码和图示,读者可以清晰地了解state和context在React组件中的应用和传递方式。最后,文章提到了基于数据流进行组件拆分的重构工作,为下节课的重构工作做好充分准备。整体而言,本文通过深入浅出的方式介绍了React组件之间的数据流转,对于想要快速了解React组件间数据流转的开发者来说,是一篇值得阅读的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 React Web 开发实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • 🐑
    置顶
    你好,我是《现代React Web开发实战》的编辑辰洋,这是👇项目的源代码链接,供你学习与参考:https://gitee.com/evisong/geektime-column-oh-my-kanban/releases/tag/v0.12.0
    2022-09-19归属地:北京
    3
    1
  • 海华呀
    1、因为一个父组件可能有多个子组件,如果任意子组件都可以修改父组件数据,可能会导致其他子组件受到影响,这样以来会加大开发和debug难度,单向数据流就没这个影响。

    作者回复: 你好,海华呀,这个反例举得太好了。单向数据流是React框架的一项重要的设计哲学,乍一看有些教条,但它很有力地保证了数据的秩序,减少了开发者的混乱。

    2022-10-19归属地:北京
    4
  • 01
    state 其实应该可变可不变的。 变是因为实打实的值变了, 不变是UI在当下不变

    作者回复: 你好,01,确实state的变化最终会导致UI的变化。这里提到的state不可变,更多是在强调对于开发者的约束,只有调用 setXxxState() 产生的变更,才能被React“观测”到,触发接下来的渲染、提交过程。

    2022-09-29归属地:北京
  • 船长
    有一个细节疑问:在重构 css 时,vscode 中有 4 个选项,宋老师用的是“抽取为模块范围的常量”, 实际效果是将这块代码放到了根目录下。我试了下另一个选项(第一个选项)“抽取为封闭范围的常量”,发现 vsc 将其放到了 KanbanBoard 这个函数的大括号下。 想问下这 2 块有什么区别吗?

    作者回复: 你好,船长,因为在emotion方案中,JSX的css属性值是执行 @emotion/react的 css()函数(即css`args`) 函数的结果,所以你提到的两个位置就是 css()函数 执行次数的区别。模块范围的常量,意味着这个模块只要被加载,就会被执行一次,且只有这一次;KanbanBoard函数大括号内,意味着组件每次重新渲染都会执行一次 css()函数。

    2022-09-21归属地:北京
  • DullSword
    1.使数据流向简单清晰,多向可能会带来复杂和混乱。 2.我理解的重构是改进代码,可能是改进代码的结构,也可能是改进代码的运行效率。

    作者回复: 你好,DullSword,你对这两个问题的思路是对的,当然如果能再详细些就更好了。比如1里你提的混乱,有没有想到哪些具体的例子?

    2022-09-20归属地:北京
  • 船长
    所谓重构(refactoring)是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。重构是一种经千锤百炼形成的有条不紊的程序整理方法,可以最大限度地减小整理过程中引入错误的概率。本质上说,重构就是在代码写好之后改进它的设计。 Ref: 《重构》 马丁 福勒

    作者回复: 你好,船长,很棒的答案!话说Martin Fowler大神的很多观点,我都是工作很久以后才真正理解的,很佩服他的丰富经验和深入思考。

    2022-09-20归属地:北京
  • 学习前端-react
    请问:类似于redux 这样的状态管理器也都是基于 context 去实现的吧。

    作者回复: 你好,学习前端-react,也是也不是。 首先redux是一个框架无关的应用状态管理框架,也可以用于vue或svelte等框架。我们在React中使用redux,一般会借助redux官方的React连接器 react-redux。 这个库把redux的store放到了context里,但并没有借助React的context更新机制来响应store内部的更新。在早期版本中,react-redux提供的高阶组件订阅store变化,当有变化时调用组件的forceUpdate()方法,具体可以参考:https://gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424e ;而在新版中,高阶组件使用了React的新Hooks API:useSyncExternalStore,用这个Hook返回的props来更新被修饰的组件,具体请参考 https://github.com/reduxjs/react-redux/blob/70a167e5fa6b311338d98e26b3a855ba44d7c739/src/components/connect.tsx#L707。 如果你感兴趣,可以读一读react-redux的发展史: https://blog.isquaredsoftware.com/2018/11/react-redux-history-implementation/

    2022-09-17归属地:北京
    5
  • 潮汐
    Context.Provider 的 value 值也可以传一个对象进去,但要注意写法,避免在组件重新渲染时反复创建新的对象,比如利用 state 或 useMemo : -------------------------------------------------- 问下老师,这里说的要避免的写法,是为了单纯避免value值的对象的重复创建,还是说避免重复创建对象防止多余重复渲染啊。试验了一下,文中value值的对象形式,不管哪种形式,对象字面了,state对象值,useMemo值,在状态更新时,子孙组件都会重新渲染。所以我觉得老师这里的意思是 避免每次组件更新渲染时重新创建value值的对象。然而这里,不管是否重新创建value值的对象,子孙组件都会更新渲染。
    2023-01-11归属地:广东
    1
    1
  • 船长
    思考题2: 个人理解重构是为了降低代码耦合度,减少系统的熵,方便后续增补或阅读
    2022-09-20归属地:上海
    1
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部