Redux 作为 React 全家桶的一名重要成员,在众多大牛的力荐之下得到了广泛的应用,Github 上的 Star 也达到 42k 之多!然而,当触及最根本的问题,为什么要使用 Redux 的时候,很多人是说不清楚的。本文尝试解读 Redux 的设计初衷,并结合 React 谈谈实际的使用场景。本文只谈理论,不会对 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 在某个状态下的视觉呈现。

页面的切换,可以简单理解为 Model 的状态变迁(同时也会涉及到 UI 的状态变迁)。数据的状态和 UI 的状态,下文统一称为 state。
那么,为什么需要专门有一个工具来管理 state 呢?先来看看下面这张图:

这是一张backbone的数据流图,一个 View 可能涉及到多个 Model,当用户操作 View 的时候,可能引发多个 Model 的更新,而 Model 的更新又会引发另一个 View 的改变。View 与 Model 之间的关系错综复杂,如果想要添加一个功能或者修改 bug,都要花大量的时间进行调试,还容易出问题。
你也许会说,使用 React 就不会遇到这种问题,因为 React 天然就是使用 state 来管理界面的展示,state 与 View 一一对应,这与 Redux 的思想是契合的。然而,随着应用复杂度的增加,你会经历以下心路历程:



共享的state需要放在最顶层维护,然后一层一层地往下传递修改state的方法和展现的数据。这时你会发现,很多数据中间层的组件根本不需要用到,但由于子组件需要用,不得不经过这些中间层组件的传递。更令人头疼的事,当state变化的时候,你根本分不清楚是由哪个组件触发的。

应用的state统一放在store里面维护,当需要修改state的时候,dispatch一个action给reducer,reducer算出新的state后,再将state发布给事先订阅的组件。
所有对状态的改变都需要dispatch一个action,通过追踪action,就能得出state的变化过程。整个数据流都是单向的,可检测的,可预测的。当然,另一个额外的好处是不再需要一层一层的传递props了,因为Redux内置了一个发布订阅模块。

Redux虽好,但并不适用于所有项目。使用Redux需要创建很多模版代码,会让 state 的更新变得非常繁琐,谁用谁知道
正如 Redux 的作者 Dan Abramov 所言,Redux 提供了一个交换方案,它要求应用牺牲一定的灵活性以达到以下三个要求:
相应的,你会得到以下好处:
另外,对于 React 来说,当遇到以下情况你或许需要 Redux 的帮助:
Redux 是一个为 JavaScript 应用设计的,可预测的状态容器。在使用之前,最好先弄清楚他能为你的程序带来什么,需要你做出怎样的妥协,也就是上文提到的交换方案。希望读完本文后,你对Redux 的设计思想与使用场景有一个更全面的了解。