昨天花了很久的时间,终于有些理解Redux了。根据官方的文档也做出了一个例子而且运用到我的项目中去。
关于Redux
对于我了理解其实Redux就是一个能整合所有数据的大的State,它方便了组件之间的数据交流,一般的组件数据都是自上而下的通过props进行传递,而这样做的后果就是造成,对于一个嵌套了很多层的组件来讲,这样的实现方式就会显得相当麻烦,最顶层的组件不得不通过一层层的props来去和目标组件进行数据交换,这样产生的后果是造成了大量了性能缺失。而且如果两个组件拥有各自的state,但是需要进行数据交流的话,通过props进行交流这种方法就不能实现了。
早期FaceBook通过Flux来解决这一个问题,React内部也有一个context的API来解决这种问题,直到后来Redux出现了,它基于Flux的设计理念,即Vevw层不允许直接修改应用状态,只能触发Action,应用的状态必须独立出来放到store里面统一管理,通过监听Action来执行具体的状态操作。
即View->Action->Store->View,这样视图组件的功能只是展示,Action用来分发事件,dispatcher接受Action来处理事件改变Store,Store的改变又是的View层重新渲染。
单向数据流是Redux的核心理念,所有的状态变化都可以被记录,跟踪,组件的数据只有唯一的出口及入口,这样程序显得更加直观,通俗的讲,找起Bug来比较容易(手动滑稽).
Redux的实现流程
再不考虑异步的情况下,Redux的实现方式十分简单,其实异步也不难。
Action
一般的流程首先是先创建Action,Action一般是一个对象,对象必须包含一组键值对,type属性,type的值必须是字符串,这并不代表type的值必须是字符串属性的,只要是输出的为字符串就行,比如字符串赋值的变量,一个函数的返回值为字符串也行,Action中也可以包含其他的值,一般都有什么值呢?请移步我之前的一篇博客关于Redux中的有关于Action的社区内规范。
Action的种类取决于你的组件内需要交互的种类有多少,一般在一个组件内,Action的种类应该相当繁杂,你可以写在一个Action.js中,当然你也可以写在你的各个组件内的action.js内,每个组件掌管自己的action,我们一般使用一个函数来生产Action,毕竟一个一个的写比较麻烦。
上面的函数就是一个生产Action的组件,其中index是一个简写的方式,相当于{index:index}
Store
Store相当于是一个应用中最顶层的state的身份,它包含了一个应用内所有的数据,通过createStore()函数可以返回一个Store,通常一个应用内只能使用一个Store,所有的应用数据都在这个Store中,每个组件通过’connect’这个Redux中的API来获取Store中的一些数据,connect类似于筛选器这么一个功能,他接受一个函数,这个函数一般用来返回Store的数据所用的,你可以在这个函数内选取自己需要的的数据值,举个例子吧。
|
|
Reducer
Reducer类似于加工厂的身份,他接受两个参数,一个是Store,一个是action,Store是我们通过createStore()这个API得来的,reducer将获取的两个参数进行加工,然后就会返回一个新的Store。reducer会通过比对Action中的type值来返回不同的结果,所以这就是为什么我们需要给Action加type键值对的根本原因。下面就是一个有关于reducer的流程演示(不代表真是代码)的伪代码.
|
|
Reducer函数有点类似于React中的setState,它不允许你直接修改Store的数值,他只能让你返回一个新的Store,所以尽量避免直接在Reducer函数内直接修改Store这样的操作,如果Store是一个数组,那么我们就使用slice这样的方式增删改查,如果Store是一个对象,我们可以使用Object.assign()来进行操作,当然我们也可是使用immuatble.js来进行Store的修改,只要记住一点,Reducer不能直接修改Store的属性就好。
这是因为Redux自身的diff算法造成的,如果我们直接修改Store,就会使得Redux自身监听不到Store的修改,从而无法让整个组件重新渲染。
还有Reducer是一个纯函数,关于什么是纯函数,请移步阮一峰的Redux教程。
store.dispatch()
store.dispatch()是View组件唯一能发出Action的方法,前面讲的Reducer接受一个Action不是吗?所以如何将我们所需要的Action发射出去呢,这就需要我们使用store.dispatch()来发送给Reducer了,比如点击一个页面元素,我们就必须把这个dispatch()绑定在这个元素上。看如下一个伪代码。
|
|
上面的代码就是整个改写的过程,但是实际操作肯定比这个要复杂的多,你可以在网上找相关的资料来看,这个文章只是告诉你,Redux的大体流程,在脑海中有个相关的概念,之后在理解Redux就没那么困难了