Redux设计思想与使用场景

欢迎关注个人公众号睿Talk,获取我最新的文章:
clipboard.png前端

1、前言

Redux 做为 React 全家桶的一名重要成员,在众多大牛的力荐之下获得了普遍的应用,Github 上的 Star 也达到 42k 之多!然而,当触及最根本的问题,为何要使用 Redux 的时候,不少人是说不清楚的。本文尝试解读 Redux 的设计初衷,并结合 React 谈谈实际的使用场景。本文只谈理论,不会对 Redux 的使用做过多的介绍。segmentfault

2、Redux 设计思想

如何用一句话来描述 Redux ?官网是这么写的:设计模式

Redux is a predictable state container for JavaScript apps.
Redux是一个为JavaScript应用设计的,可预测的状态容器。

因而可知,Redux的主要做用是管理程序状态的。这里所说的状态指的是数据状态,也就model的状态( state )。当今流行的前端框架,都是使用 MVVM 的设计模式,也就 Model,View,View-Model。框架承担了大部分 View-Model 的工做,咱们只须要把 Model 和 View 的映射关系定义清楚就行。用公式描述就是View = Render(Model)。因此本质来讲,用户看到的页面,是Model 在某个状态下的视觉呈现。数组

clipboard.png

页面的切换,能够简单理解为 Model 的状态变迁(同时也会涉及到 UI 的状态变迁)。数据的状态和 UI 的状态,下文统一称为 state。前端框架

那么,为何须要专门有一个工具来管理 state 呢?先来看看下面这张图:服务器

clipboard.png

这是一张backbone的数据流图,一个 View 可能涉及到多个 Model,当用户操做 View 的时候,可能引起多个 Model 的更新,而 Model 的更新又会引起另外一个 View 的改变。View 与 Model 之间的关系错综复杂,若是想要添加一个功能或者修改 bug,都要花大量的时间进行调试,还容易出问题。网络

你也许会说,使用 React 就不会遇到这种问题,由于 React 自然就是使用 state 来管理界面的展现,state 与 View 一一对应,这与 Redux 的思想是契合的。然而,随着应用复杂度的增长,你会经历如下心路历程:app

  • 刚开始的时候,只须要作一些简单的展现,只要在顶层的组件获取数据后再以 props 的形式传给子组件就行了:

clipboard.png

  • 当加入交互功能后,兄弟组件之间须要共享 state 了,当组件一修改后组件二也要同步更新。React 的解决方案是状态提高(Lifting State Up),经过父组件来统一更新 state,再将新的state 经过 props 传递下去:

clipboard.png

  • 随着功能的不断丰富,组件愈来愈多,state也愈来愈复杂,直到有一天你发现,修改和共享某个state变得极其艰难:

clipboard.png

共享的state须要放在最顶层维护,而后一层一层地往下传递修改state的方法和展示的数据。这时你会发现,不少数据中间层的组件根本不须要用到,但因为子组件须要用,不得不通过这些中间层组件的传递。更使人头疼的事,当state变化的时候,你根本分不清楚是由哪一个组件触发的。框架

  • 这时候若是使用Redux对应用进行重构,状态的变化就会变得很是清晰:

clipboard.png

应用的state统一放在store里面维护,当须要修改state的时候,dispatch一个action给reducer,reducer算出新的state后,再将state发布给事先订阅的组件。分布式

全部对状态的改变都须要dispatch一个action,经过追踪action,就能得出state的变化过程。整个数据流都是单向的,可检测的,可预测的。固然,另外一个额外的好处是再也不须要一层一层的传递props了,由于Redux内置了一个发布订阅模块。

clipboard.png

3、使用场景

Redux虽好,但并不适用于全部项目。使用Redux须要建立不少模版代码,会让 state 的更新变得很是繁琐,谁用谁知道

正如 Redux 的做者 Dan Abramov 所言,Redux 提供了一个交换方案,它要求应用牺牲必定的灵活性以达到如下三个要求:

  • 经过简单对象和数组描述应用状态
  • 经过简单对象描述应用状态的改变
  • 使用纯函数来描述状态改变的逻辑

相应的,你会获得如下好处:

  • 能够很方便的将 state 存储到 Local Storage 中并在须要的时候取出并启动应用
  • 能够在服务器端直接计算出 state 再存到 HTML 中,而后在客户端秒开页面
  • 方便的序列化用户操做和对应的 state 快照,在出现 bug 的时候能够利用这些信息快速复现问题
  • 经过在网络中传递 action 对象,能够在对代码进行很小改动的状况下实现分布式应用
  • 能够在对代码进行很小改动的状况下实现撤销和恢复功能
  • 在开发过程当中能够任意跳转到应用的某个历史状态并进行操做
  • 提供全面的审查和控制功能,让开发者能够定制本身的开发工具
  • 将 UI 和业务逻辑分离,使业务逻辑能够在多个地方重用

另外,对于 React 来讲,当遇到如下状况你或许须要 Redux 的帮助:

  • 同一个 state 须要在多个 Component 中共享
  • 须要操做一些全局性的常驻 Component,好比 Notifications,Tooltips 等
  • 太多 props 须要在组件树中传递,其中大部分只是为了透传给子组件
  • 业务太复杂致使 Component 文件太大,能够考虑将业务逻辑拆出来放到 Reducer 中

4、结语

Redux 是一个为 JavaScript 应用设计的,可预测的状态容器。在使用以前,最好先弄清楚他能为你的程序带来什么,须要你作出怎样的妥协,也就是上文提到的交换方案。但愿读完本文后,你对Redux 的设计思想与使用场景有一个更全面的了解。

相关文章
相关标签/搜索