浅谈 React、Flux 与 Redux

React

React 是一个 View 层的框架,用来渲染视图,它主要做几件事情:

  • 组件化
  • 利用 props 形成单向的数据流
  • 根据 state 的变化来更新 view
  • 利用虚拟 DOM 来提升渲染性能

前面说到 React 能够根据 state 的变化来更新 view,一般来说引起 state 变化的动作除了来自外部(如服务器),大部分都来自于页面上的用户活动,那页面上的用户活动怎样对 state 产生作用呢?React 中每个组件都有 setState 方法用于改变组件当前的 state,所以可以把更改 state 的逻辑写在各自的组件里,但这样做的问题在于,当项目逻辑变得越来越复杂的时候,将很难理清 state 跟 view 之间的对应关系(一个 state 的变化可能引起多个 view 的变化,一个 view 上面触发的事件可能引起多个 state 的改变)。我们需要对所有引起 state 变化的情况进行统一管理,于是就有了 Flux。

Flux

Flux 是一种应用架构,或者说是一种思想,它跟 React 本身没什么关系,它可以用在 React 上,也可以用在别的框架上。前面说到 Flux 在 React 中主要用来统一管理引起 state 变化的情况。Flux 维护着一个或者多个叫做 Store 的变量,就像 MVC 里面的 Model,里面存放着应用用到的所有数据,当一个事件触发时 ,Flux 对事件进行处理,对 Store 进行更新,当 Store 发生变化时,通常是由应用的根组件(也叫 controller view)去获取最新的 store,然后更新 state,之后利用 React 单向数据流的特点一层层将新的 state 向下传递实现 view 的更新。这里的 controller view 可以有多个也可以不是根组件,但是这样数据流维护起来就比较麻烦。

Flux 的思维模型如下:

Flux 主要包括四个部分,DispatcherStoreViewAction,其中 Dispatcher 是 Flux 的核心枢纽,它相当于是一个事件分发器,将那些分散在各个组件里面的逻辑代码收集起来,统一在 Dispatcher 中进行处理。完整的 Flux 处理流程是这样的:用户通过与 view 交互或者外部产生一个 Action,Dispatcher 接收到 Action 并执行那些已经注册的回调,向所有 Store 分发 Action。通过注册的回调,Store 响应那些与他们所保存的状态有关的 Action。然后 Store 会触发一个 change 事件,来提醒 controller-views 数据已经发生了改变。Controller-views 监听这些事件并重新从 Store 中获取数据。这些 controller-views 调用他们自己的 setState() 方法,重新渲染自身以及组件树上的所有后代组件。使用 Flux 有个好处就是我只需要用 action 对象向 Dispatcher 描述当前的事件就可以执行对应的逻辑,因为 Dispatcher 是所有 Action 的处理中心,即使没有对应的事件发生,我们也可以“伪造”一个出来,非常利于测试。

Redux

Redux 的作用跟 Flux 是一样的,它可以看作是 Flux 的一种实现,但是又有点不同,具体的不同总结起来就是:

1. Redux 只有一个 store

Flux 里面会有多个 store 存储应用数据,并在 store 里面执行更新逻辑,当 store 变化的时候再通知 controller-view 更新自己的数据,Redux 将各个 store 整合成一个完整的 store,并且可以根据这个 store 推导出应用完整的 state。同时 Redux 中更新的逻辑也不在 store 中执行而是放在 reducer 中。

2. 没有 Dispatcher

Redux 中没有 Dispatcher 的概念,它使用 reducer 来进行事件的处理,reducer 是一个纯函数,这个函数被表述为 (previousState, action) => newState,它根据应用的状态和当前的 action 推导出新的 state。Redux 中有多个 reducer,每个 reducer 负责维护应用整体 state 树中的某一部分,多个 reducer 可以通过 combineReducers 方法合成一个根reducer,这个根reducer负责维护完整的 state,当一个 action 被发出,store 会调用 dispatch 方法向某个特定的 reducer 传递该 action,reducer 收到 action 之后执行对应的更新逻辑然后返回一个新的 state,state 的更新最终会传递到根reducer处,返回一个全新的完整的 state,然后传递给 view。

在我看来,Redux 和 Flux 之间最大的区别就是对 store/reducer 的抽象,Flux 中 store 是各自为战的,每个 store 只对对应的 controller-view 负责,每次更新都只通知对应的 controller-view;而 Redux 中各子 reducer 都是由根reducer统一管理的,每个子reducer的变化都要经过根reducer的整合。用图表示的话可以像这样:

Flux 中的 store 是这样的:

Redux 中的 store(或者叫 reducer)是这样的:

ps:刚接触 React,很多地方了解地不是特别深入,如有错漏,欢迎指正。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Modeng的专栏

Vue中如何使用方法、计算属性或观察者

熟悉 Vue 的都知道 方法methods、计算属性computed、观察者watcher 在 Vue 中有着非常重要的作用,有些时候我们实现一个功能的时候可以...

1092
来自专栏偏前端工程师的驿站

JS魔法堂:jsDeferred源码剖析

一、前言                                最近在研究Promises/A+规范及实现,而Promise/A+规范的制定则很大程度地...

1917
来自专栏追不上乌龟的兔子

Python3.7的新API:asyncio.run()

Python3.7的正式版本已经发布有一段时间了,出了内置的breakpoint()断点函数,颇受争议的dataclass,自定义模块里的__getattr__...

3716
来自专栏大内老A

WCF技术剖析之十一:异步操作在WCF中的应用(上篇)

按照操作执行所需的资源类型,我们可以将操作分为CPU绑定型(CPU Bound)操作和I/O绑定型(I/O Bound)操作。对于前者,操作的执行主要利用CPU...

1847
来自专栏较真的前端

Vue相关的前端面试题,每道题都很经典~

1.7K3
来自专栏阮一峰的网络日志

如何做到 jQuery-free?

jQuery是现在最流行的JavaScript工具库。 据统计,目前全世界57.3%的网站使用它。也就是说,10个网站里面,有6个使用jQuery。如果只考察使...

2994
来自专栏风中追风

高效编程之HashMap的entryset和keyset比较

最近看了一点spring的源码,甚是苦涩;对spring稍微有了点整体的认识,但对很多细节的地方还是懵逼啊。。。太多不懂了的,只能慢慢去读,先把简单的不懂的解决...

34510
来自专栏达摩兵的技术空间

js代码优化日常001

本文开始针对项目中总结出来的关于js基础知识的代码优化技巧进行每个细节点的分析,后续还会针对某个专题的分析。

803
来自专栏算法channel

其他|c++几个容易混淆的点

希望时间的流逝不仅仅丰富我们的阅历,更重要的是通过提炼让我们得以升华,走向卓越。 1编译出错 一段时间没写c/c++的程序了,最近公司一个项目底层的核心算法是...

3155
来自专栏代码世界

23种设计模式之单例模式

单例模式    单例模式(Singleton Pattern)是一个比较简单的模式,其定义为:Ensure a class has only one insta...

32814

扫码关注云+社区