数据流 in redux

Posted Levitt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据流 in redux相关的知识,希望对你有一定的参考价值。

前不久用react和react-router写了个单页面应用,但写完后总感觉还欠缺点什么,组件间的状态和数据相对较为独立,而且兄弟组件间的通信很不方便。然后才了解到,在react应用中,可以存在一个负责整合数据流向的框架,于是就选择了redux.

根据我的理解下面说一下redux的思想:

redux由三个部分组成,即store,reducer以及action,直观一点,你可以把store理解为数据库,reducer是事件处理函数,action是触发事件。为什么可以这么理解呢,因为整个redux的大致逻辑是这样的:

1 dispatch(action),即触发action,(事件发生)

2 reducer根据当前所触发action执行相对应的函数,更新state,(执行事件处理函数,更新数据库数据)

3 store的state会为应用所获取,像数据库一样

当然可能并不是那么契合,但大致的可以这么理解。现在我们再仔细的看一看redux的数据流。

1 dispatch的action会被reducer捕获到,其实是action先被传送至store,再由store交付给reducer的,因为dispatch是store的方法,action通过回调到达的store,而之前我们在创建store的时候使用了这样的声明 var store = createStore(reducer),使得store与reducer建立了某种联系,自然的,reducer能够接收到触发的action。

2 上面是redux内部数据流的实现,但是redux与应用之间的数据流动是怎么建立起来的呢?因为一般来说,是由应用的视图触发action,然后redux的reducer根据接收到的action执行相应的处理函数更新store的state,而state又是作为数据来源与应用绑定的,所以store的state一更新,应用视图也会同步刷新。所以这里的问题是,应用是如何获得dispatch action的能力以及来自store的数据的呢?这个就需要借助react-redux的Provider以及connect组件了。

通过Provider组件为应用组件再加一层外壳,并传入整个应用的store。

 
connect组件负责链接store与应用。其中select函数会接收到来自store的state,在这里可以对state进行相应的预处理再返回应用所需state,state会连同store的dispatch方法以属性方式传入App组件即应用组件。
 
 

todo项目,说明整个项目的核心思想

redux的数据流思想大致如此,但这只是我自己的理解,可能会有所纰漏。

看了redux官方文档之后,照着葫芦画瓢也实现了一个todo小应用。


 

整个应用的编写思路其实不外乎上面所谈及的那些。

但是需要注意的是,上面截图中的第一条todo其实是通过异步添加上去的,然而dispatch只能触发同步的action,即传递普通的action对象,因为这样我们的action才能被reducer所接收到并触发相对应的处理函数。所以,如果需要触发异步的action的话,常规的方法是不行了的,我们需要使用点小技巧。这里又涉及到redux中间件(middleware)的概念了。简单介绍下,所谓中间件,就是在action被触发以及还没被reducer接收到之间这段时间所执行的一段函数,其内部封装有dispatch方法。中间件的存在是dispatch扩展的唯一标准方式。

我们想要使用中间件的话,需要借助applyMiddleware方法,它能够使中间件与store建立某种联系,使得store的dispatch和getState方法传入中间件。

说回我们之前所说的异步action,异步请求的实现我们可以借助于redux-thunk中间件,这个中间件会去拦截异步action,因为一般情况下异步action是action创建函数所返回的一个函数,所以redux-thunk中间件会替我们去执行这个函数。执行的最后,一般会dispatch普通的action对象,reducer捕获到此action对象,做出相应。

这是我们的异步action创建函数,会返回一个异步函数

//异步action
export function asyncAction(){
    return function(dispatch, getState){
        setTimeout(function(){
            dispatch(addTodo("2秒钟过去啦!你还没添加新的任务,我来帮你添加一个吧!"))
        },2000)
    }
};

然后我们dispatch它

dispatch(asyncAction());

因为返回的是异步action对象(函数),会被redux-thunk拦截并执行,执行的最后dispatch一个普通的action事件,成功添加一条todo。

完整的代码在这里 https://github.com/JerelLin/redux-todo

 

睡觉

以上是关于数据流 in redux的主要内容,如果未能解决你的问题,请参考以下文章

“ES7 React/Redux/GraphQL/React-Native 片段”不适用于 javascript 文件。除了安装它,我还需要配置其他东西吗?

ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)(代码片段

next-redux-wrapper TypeError: nextCallback is not a function error in wrapper.getServerSideProps

一旦单击带有 in 片段的回收器列表项,如何将片段意向活动,以及如何获取回收器项目值?

What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段

imgwarp.cpp:3143: error: (-215:Assertion failed) _src.total() > 0 in function ‘warpPerspective‘(代码片段