摘要:光凭一个是无法实现血缘关系疏远的组件之间的状态同步的。就是为解决这个问题而生的。,处理动作的派发,相当于架构的。我们的主角是,它也是目前社区最受欢迎的状态管理框架。专题一览考古实用中间件时间旅行
本文是『horseshoe·Redux专题』系列文章之一,后续会有更多专题推出
来我的 GitHub repo 阅读完整的专题文章
来我的 个人博客 获得无与伦比的阅读体验
React的横空出世给前端带来一场革命。其实随React一同开源的还有一个叫Flux的东西。Flux是管理应用状态的一种架构。光凭一个props是无法实现血缘关系疏远的组件之间的状态同步的。虽然context加回调可以勉强做到这一点,但是Flux架构有其更加深远的意义。
你看,从一开始facebook的工程师就知道只凭React无法支撑大型的应用开发。但是为什么称Flux为一种架构而不是一个类库或者框架呢?因为它的出现主要是为了提出一种思想,而不是作为一个真正成熟的类库。facebook的工程师希望社区根据这种思想涌现出多样化的实现方式。
那么,Flux提出的思想是什么呢?
这一切还要从MVC架构说起。
MVC以前端举例,MVC架构将一个应用分为Model 、View和 Controller三部分。Model 代表数据模型,用来存放业务逻辑;View代表视图,是最终的界面效果;Controller代表控制器,响应用户的操作。
一个用户操作View发出指令,Controller处理该指令并且将处理结果传递给Model,Model再将更新后的数据渲染到View上。
当一个应用越来越复杂时,如何去维护庞大的代码和让新人快速的上手就变的紧迫起来。MVC架构的分层思想就是服务于这一目的,它并不能让应用的性能提升,但是它可以让代码对开发者更友好。不过影响代码对开发者友好度的可不止这一点,更重要的是数据的流向在开发者面前的清晰度。
MVC架构有没有对数据的流向做很好的控制呢?并没有。它有一套理想中的流程,就是上面讲到的视图更新的操作过程,然而View可不可以直接给Model发指令?当然可以,并且很多开发者就是这么做的。如果每一层都可以和每一层通信,代码的可读性将变的混乱不堪。
FluxFlux就是为解决这个问题而生的。MVC架构的问题在于没有严格控制数据的流向,所以facebook的工程师将Flux设计成数据只能走单通道,一个特定的操作才能触发另一个特定的操作。
一个Flux应用包含四部分:
Action,一个动作对象,相当于用户的指令。
Dispatcher,处理动作的派发,相当于MVC架构的Controller。
Store,负责存储数据,相当于MVC架构的Model。
View,和MVC架构一样。
用户触发View上的事件发送Action,Action只能通过Dispatcher.dispatch方法发送出去,Store更新自身的数据然后View根据Store重新渲染。一环扣一环,只能按照这个流程走下去。
这就是我们说的单向数据流。
至此,我们实现了功能的分层和数据的单向流动,代码不再那么混乱了。
Redux我们的主角是Redux,它也是目前React社区最受欢迎的状态管理框架。实际上,Redux就是Flux的门徒之一。它如此受欢迎,一定是因为它在Flux的基础上做对了什么事情。
Flux解决了单向数据流的问题,那么Redux解决了什么问题呢?
我认为Redux的贡献主要是这两点:
推崇唯一数据源。
加入函数式编程思想。状态只读和只能通过纯函数来改变状态都是函数式编程的特性,目的就是为了改变状态的过程中不产生副作用。
咱们先来说说唯一数据源是怎么回事?
Flux的设计是将每一块相对独立的状态分别用一个Store来存储。这样的好处是显而易见的,每一个Store的体积都足够小,对象的嵌套不会很深。
坏处是什么呢?
Dispatcher在派发动作的时候,会依次访问每一个Store。这样虽然会损失一些性能,但是Dispatcher的逻辑可以做到极简,它不用知道这个动作应该派发给谁,都给它们发一遍得了。假如Store A对Store B存在依赖关系,那么它们的状态更新顺序就很重要,而Dispatcher哪管这些个儿女情长。于是开发者需要通过Dispatcher注册回调函数返回的token来手动管理Store之间的依赖关系。
这无疑又是对开发者不友好的设计。
所以Redux干脆,只维护一个全局的Store,让你开发者再哔哔哔。正事不干,就知道哔哔哔。
需要注意的是,Redux并没有从机制上阻止开发者使用多个Store管理应用,开发者还是可以作妖的。不过这又回到Flux的老路上去了,对开发者一点好处都没有。Redux选择用思想和约定来约束开发者。
再来说函数式编程。
函数式编程思想的提出最早是为了处理复杂的计算任务。计算任务的要求是什么呢?结果可预期,任务之间不会相互影响。
相同的输入,总是有相同的输出。对应到函数,就是不能修改已有的数据,只要修改已有的数据,理论上就有可能输出不同的结果。那么我确实有修改数据的需求怎么办?生成一个新的衍生数据。
执行某个任务不会对外部产生影响,也就是所谓的没有副作用。
我们想一下,Redux加入函数式编程思想的目的不还是为了让单项数据流更加清晰和单纯么?
Redux给前端带来的另一个重大成果是时间旅行式的调试。开发者可以回到任意时间点的案发现场,看看那个臭虫到底是哪个阴沟里生出来的。
如果你看完本专题,就会发现Redux的作者Dan Abramov从一开始设计Redux就是奔着时间旅行式的调试去的。时间旅行才是Redux写法这么繁琐的罪魁祸首。
所以Flux的历史功绩是为前端引入了一种思想,而Redux仅仅是改进这种思想而已,还算不上一代宗师。不过Redux本来就是Flux的门徒之一,作为门徒能够将师门发扬光大也是一代豪杰了。
Redux专题一览考古
实用
中间件
时间旅行
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97891.html
摘要:在英文中的意思是有效载荷。有一个动作被发射了顾名思义,替换,这主要是方便开发者调试用的。相同的输入必须返回相同的输出,而且不能对外产生副作用。怎么办呢开发者得手动维护一个订阅器,才能监听到状态变化,从而触发页面重新渲染。 本文是『horseshoe·Redux专题』系列文章之一,后续会有更多专题推出来我的 GitHub repo 阅读完整的专题文章来我的 个人博客 获得无与伦比的阅读体...
摘要:好处就是不再需要能够处理异步的中间件了。不过,它是一个研究中间件很好的范本。执行它,返回的是由第二层函数组成的中间件数组。也就是说呀同学们,除了最后一个中间件的是原始的之外,倒数往前的中间件传入的都是上一个中间件的逻辑函数。 本文是『horseshoe·Redux专题』系列文章之一,后续会有更多专题推出来我的 GitHub repo 阅读完整的专题文章来我的 个人博客 获得无与伦比的阅...
摘要:我们可以为元素添加属性然后在回调函数中接受该元素在树中的句柄,该值会作为回调函数的第一个参数返回。使用最常见的用法就是传入一个对象。单向数据流,比较有序,有便于管理,它随着视图库的开发而被概念化。 面试中问框架,经常会问到一些原理性的东西,明明一直在用,也知道怎么用, 但面试时却答不上来,也是挺尴尬的,就干脆把react相关的问题查了下资料,再按自己的理解整理了下这些答案。 reac...
摘要:官网也给出了范例,以下代码可以实现一个拦截器问题描述但在之前,执行上述官方给出的代码是会报错的。可以获取拦截器服务的实例们。 原文首发于 baishusama.github.io,欢迎围观~ 前言 恍然间发现这个错误已经不复存在了,于是稍微看了下相关 issue、commit、PR。写篇笔记祭奠下~ 需求描述 一个使用 HttpInterceptor 的常见场景是实现基于 token ...
摘要:深入之继承的多种方式和优缺点深入系列第十五篇,讲解各种继承方式和优缺点。对于解释型语言例如来说,通过词法分析语法分析语法树,就可以开始解释执行了。 JavaScript深入之继承的多种方式和优缺点 JavaScript深入系列第十五篇,讲解JavaScript各种继承方式和优缺点。 写在前面 本文讲解JavaScript各种继承方式和优缺点。 但是注意: 这篇文章更像是笔记,哎,再让我...
阅读 3178·2021-11-23 09:51
阅读 3629·2021-09-22 15:35
阅读 3628·2021-09-22 10:02
阅读 2917·2021-08-30 09:49
阅读 478·2021-08-05 10:01
阅读 3355·2019-08-30 15:54
阅读 1609·2019-08-30 15:53
阅读 3531·2019-08-29 16:27