Redux是如何工作的
最近一次面试中,我遇到了一个问题:在一个基础的TODO应用中Redux是如何工作的。我需要告诉面试官当输入表单和点击提交按钮时会发生什么。当时我面前没有电脑,只有他给我一张纸和简历的背面。
手里拿着笔,我坐着想了一会。
我之前也遇到过这种情况——在技术面试部分,我就像一头小鹿。幸运的是,我已经克服了在前几次技术面试中的困难,所以这种情况还不算糟糕。
其实,面试是一门技能,要想做得更好,就得不断失败,因为只有在失败中你才能发现你的弱点,才能不断进步。这也是为什么我喜欢写我面试中被问到的问题的原因。它会使我深入研究问题背后的原理并变得更好。同时我建议其他人也这样做。
持续学习,持续进步!
首先,什么是Redux?
Redux官方文档描述如下:
Redux is a predictable state container for JavaScript apps. (Not to be confused with a WordPress framework — Redux Framework.)
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
You can use Redux together with React, or with any other view library. It is tiny (2kB, including dependencies).
简单来说,Redux允许你在任何JavaScript框架(如React,Meteor或Angular)中管理web应用状态。
Redux的设计灵感来源于Flux,Flux是Facebook工程师创造的一种架构模式。
是什么让Redux如此特别?
简而言之,Redux为你提供了一个单一的对象,用来存放整个应用的状态——状态可能来自你的后台API或外部API的数据、导航的状态、用户的信息以及按钮的切换状态等。
它的优势在于更好的拓展性以及快速处理问题的能力。
Redux是怎么工作的?
Redux的核心概念包括: Store, Actions, Reducers, 和 Subscriptions.
Initial State(初始状态)
initial state就是状态的初始值。
当你走在杂货店的货架旁时,想想你看到了什么?有罐头、水果、面包、牛奶,以及杂货店的猫(如果你住在纽约的话):

Actions/Dispatches
接下来我们需要走进店里看看需要买什么(做什么动作,即action)。类比于Redux中,每个action都可以改变initial state,意味着你做的任何事情都可以改变你周围的东西。
我们把action的改变称之为 dispatch。

Redux — Actions
Reducers
我们现在有了action,它可以让我们进入商店并做一些动作,但现在我们还需要一些可以解释这些动作的东西。
也就是我们所说的 reducers。
Reducers接受两个参数,initial state(初始状态)和action。action决定了reducer如何处理状态。

Redux — Reducer
Store
我们有了action和能够处理action的reducer。也就是说,我们现在一旦进入杂货店,就可以与杂货店充分互动。但是,我们还需要最后一步——Store。它是state的存放容器。为了创建store,我们需要提供reducer和initial state作为参数:


Redux — Store
You can now grab the Bodega object from the store at any point using store.getState(). Let’s do that while walking through every action/dispatch:
现在你可以在任何时候使用**store.getState()**从商店里获取store对象。让我们在每次触发(dispath) action时都这样做:

Redux — 使用store.getState()获取当前state
Subscribe
You can also subscribe to the store for any changes or updates. This can be very useful as it actively listens for any actions that are dispatched that potentially change the state.
你可以使用subscribe来订阅store的改变或者更新。这可能非常有用,因为它会主动监听任何有可能改变状态的action。

Redux — Subscriptions
如上所示,当猫猫的情绪保持neutral时,第一句console.log中的内容会被输出,直到PET_BODEGA_CAT action被触发(dispatch)时,才会打印第二句console.log的内容。
应用到To Do应用中
现在我们已经初步理解redux是如何工作的了——Action通过dispatch被发送到Reducer,从而改变Store中的初始状态。我们可以把这些应用到To Do 应用中
Initial State
首先,我们需要个地方存放所有的To Do列表,这里我们用一个数组:

Redux — 初始化状态👆
Actions/Dispatches
接下来我们需要定义action来分配给Reducer。这里比上面的例子稍微有点复杂,因此这里我们需要一个动态的值。换句话说,我们需要从input中获取输入的值,所以在这里,我们的action需要传入一个参数(toDoValue)。

Redux — Action/Dispatch 👆
Reducers
我们需要一个reducer来决定需要根据action做哪些处理。

Redux — Reducer — 处理派发的action并改变状态 👆
如上面代码所示,当action ADD_TODO被调用,一旦它到了reducer中,reducer就会匹配action的类型,如果是ADD_TODE就会从action.toDo中取值并添加到数组toDos中。

整个To Do App使用Redux处理的流程如下:
- 在input中输入文本'Buy Food'
- 点击提交按钮时数据会被收集起来
- 数据传递到action中,该action通过dispath传递到Reducer中
- reducer读取action并决定如何处理
- reducer添加传递的数据到初始状态的toDos数组中
- 新的状态(新的toDos数组)被返回