-
Notifications
You must be signed in to change notification settings - Fork 442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于Redux的一些总结(一):Action & 中间件 & 异步 #35
Comments
dwqs
changed the title
关于Redux的一些总结(一):Action & 中间价 & 异步
关于Redux的一些总结(一):Action & 中间件 & 异步
Aug 24, 2016
This was referenced Sep 19, 2016
图挂了 |
领教了大神...顺便mark走了 |
写的不错 |
后面的异步没看懂😂,恩,19年的我懂了 |
学习了 |
@zhongdeming428 多谢指出 已纠正 |
向大佬学习 |
m |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
在浅说Flux开发中,简单介绍了Flux及其开发方式。Flux可以说是一个框架,其有本身的
Dispatcher
接口供开发者;也可以说是一种数据流单向控制的架构设计,围绕单向数据流的核心,其定义了一套行为规范,如下图:Redux的设计就继承了Flux的架构,并将其完善,提供了多个API供开发者调用。借着react-redux,可以很好的与React结合,开发组件化程度极高的现代Web应用。本文是笔者近半年使用react+redux组合的一些总结,不当之处,敬请谅解。
Action
Action是数据从应用传递到 store/state 的载体,也是开启一次完成数据流的开始。
以添加一个todo的Action为例:
这样就定义了一个添加一条todo的Action,然后就能通过某个行为去触发这个Action,由这个Action携带的数据(data)去更新store(state/reducer):
type
是一个常量,Action必备一个字段,用于标识该Action的类型。在项目初期,这样定义Action也能愉快的撸码,但是随着项目的复杂度增加,这种方式会让代码显得冗余,因为如果有多个行为触发同一个Action,则这个Action要写多次;同时,也会造成代码结构不清晰。因而,得更改创建Action的方式:更改之后,代码清晰多了,如果有多个行为触发同一个Action,只要调用一下函数
addTodo
就行,并将Action要携带的数据传递给该函数。类似addTodo
这样的函数,称之为 Action Creator。Action Creator 的唯一功能就是返回一个Action供dispatch
进行调用。但是,这样的Action Creator 返回的Action 并不是一个标准的Action。在Flux的架构中,一个Action要符合 FSA(Flux Standard Action) 规范,需要满足如下条件:
type
、payload
、error
和meta
中的一个或者多个属性。type
字段不可缺省,其它字段可缺省error
字段不可缺省,切必须为 truepayload
是一个对象,用作Action携带数据的载体。所以,上述的写法可以更改为:在 redux 全家桶中,可以利用 redux-actions 来创建符合 FSA 规范的Action:
可以采用如下一个简单的方式检验一个Action是否符合FSA标准:
中间件
在我看来,Redux提高了两个非常重要的功能,一是 Reducer 拆分,二是中间件。Reducer 拆分可以使组件获取其最小属性(state),而不需要整个Store。中间件则可以在 Action Creator 返回最终可供 dispatch 调用的 action 之前处理各种事情,如异步API调用、日志记录等,是扩展 Redux 功能的一种推荐方式。
Redux 提供了
applyMiddleware(...middlewares)
来将中间件应用到 createStore。applyMiddleware 会返回一个函数,该函数接收原来的 createStore 作为参数,返回一个应用了 middlewares 的增强后的 createStore。创建 store 的方式也会因是否使用中间件而略有区别。未应用中间价之前,创建 store 的方式如下:
应用中间价之后,创建 store 的方式如下:
那么怎么自定义一个中间件呢?
根据 redux 文档,中间件的签名如下:
根据上文的
applyMiddleware
源码,每个中间件接收 getState & dispatch 作为参数,并返回一个函数,该函数会被传入下一个中间件的 dispatch 方法,并返回一个接收 action 的新函数。以一个打印 dispatch action 前后的 state 为例,创建一个中间件示例:
在创建 store 的文件中调用该中间件:
可以在控制台看到输出:
可以对 store 应用多个中间件:
log2 也是一个简单的输出:
看控制台的输出:
应用多个中间件时,中间件调用链中任何一个缺少
next(action)
的调用,都会导致 action 执行失败异步
Redux 本身不处理异步行为,需要依赖中间件。结合 redux-actions 使用,Redux 有两个推荐的异步中间件:
两个中间件的源码都是非常简单的,redux-thunk 的源码如下:
从源码可知,action creator 需要返回一个函数给 redux-thunk 进行调用,示例如下:
效果如下:
这里之所以不用 createAction,如前文所说,因为 createAction 会返回一个 FSA 规范的 action,该 action 会是一个对象,而不是一个 function:
如果要使用 createAction,则要自定义一个异步中间件。
在经过中间件处理时,先判断 action.payload 是否是一个函数,是则执行函数,否则交给 next 处理:
而 async 函数返回一个 Promise,因而需要作进一步处理:
这样就自定义了一个异步中间件,效果如下:
当然,我们可以对函数执行后的结果是否是Promise作一个判断:
那么,怎么利用 redux-promise 呢?redux-promise 是能处理符合 FSA 规范的 action 的,其对异步处理的关键源码如下:
因而,返回的 payload 不再是一个函数,而是一个 Promise。而 async 函数执行后就是返回一个 Promise,所以,让上文定义的 async 函数自执行一次就可以:
结果如下图:
示例源码:redux-demo
The text was updated successfully, but these errors were encountered: