Redux 和 Redux thunk 理解
1: state 就像 model
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
2: action, 普通的 javascript 对象, 用来描述发生了什么, 里面除了type 必须的, 还会其它属性值来改变 state。
{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
3. 为了把 action 和 state 串起来, 就是 reducer, 例如下面:
reducer 一定是对应于 action 里的 type 的值, 而做变化。
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{ text: action.text, completed: false }]);
default:
return state;
}
}
Redux thunk 到底是怎么起作用的呢, 请看下面的代码:
const store = createStore(reducer, preloadedState, applyMiddleware(thunk));
当执行这个代码的时候, 实际执行了 applyMiddleware(thunk)(createStore)(reducer, preloadedState),
这个会返回一个新的 store对象, 这个 store对象的dispatch 发生了变化。
源码里首先定义原来的 store = createStore(reducer, preloadedState);
然后 thunk 里面传递下面的对象:
{
getState: store.getState,
dispatch: (action) => dispatch(action)
}
再传入原来的 store.dispatch(就是next),
返回的函数就是新的 dispatch方法:
action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
}
所以当你执行, 下面的方法判断 action 是否是函数,
dispatch( incrementAsync() );
注意下面标红的 dispatch 跟 store.dispatch 一样,所以又重新执行了1遍 dispatch = compose(...chain)(store.dispatch);
但是这个时候的 action 已经是 increment(), 不是函数了, 所以直接走到 next(action) 里面了。
function incrementAsync(delay = 1000) {
return dispatch => {
setTimeout(() => {
dispatch(increment());
}, delay);
};
}
Redux thunk 官网源码
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
//注意这里 dispatch 不用 next?
return action(dispatch, getState, extraArgument);
}
// 注意这里 next 不用 dispatch
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
applyMiddleware 源码如下:
import compose from './compose' // 这货的作用其实就是 compose(f, g, h)(action) => f(g(h(action)))
export default function applyMiddleware(...middlewares) {
return function(createStore) {
return function(reducer, preloadedState, enhancer) {
// 用原 createStore 先生成一个 store,其包含 getState / dispatch / subscribe / replaceReducer 四个 API
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch // 指向原 dispatch
var chain = [] // 存储中间件的数组
// 提供给中间件的 API(其实都是 store 的 API)
var middlewareAPI = {
getState: store.getState,
// 注意这里面的 dispatch 已经变成下面的 dispatch 了
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
// 用原来的 store.dispatch 进行窜连
dispatch = compose(...chain)(store.dispatch)
return {
...store, // store 的 API 中保留 getState / subsribe / replaceReducer
dispatch // 新 dispatch 覆盖原 dispatch,往后调用 dispatch 就会触发 chain 内的中间件链式串联执行
}
}
}
}
Redux 和 Redux thunk 理解的更多相关文章
- React-安装和配置redux调试工具Redux DevTools
chrome扩展程序里搜索Redux DevTools进行安装 新建store的时候,进行如下配置. import { createStore, applyMiddleware ,compose} f ...
- 25.redux回顾,redux中的action函数异步
回顾:Redux: 类似于 Vuex 概念:store/reducer/action action:动作 {type,.....} 一定要有type 其他属性不做限制 reducer:通过计算产生st ...
- 手把手教你撸一套Redux(Redux源码解读)
Redux 版本:3.7.2 Redux 是 JavaScript 状态容器,提供可预测化的状态管理. 说白了Redux就是一个数据存储工具,所以数据基础模型有get方法,set方法以及数据改变后通知 ...
- 记一次修改框架源码的经历,修改redux使得redux 可以一次处理多个action,并且只发出一次订阅消息
redux是一个数据状态管理的js框架,redux把行为抽象成一个对象,把状态抽象成一个很大的数据结构,每次用户或者其他什么方式需要改变页面都可以理解成对数据状态的改变,根据出发这次改变的不同从而有各 ...
- [Redux] Understand Redux Higher Order Reducers
Higher Order Reducers are simple reducer factories, that take a reducer as an argument and return a ...
- [Redux] Filtering Redux State with React Router Params
We will learn how adding React Router shifts the balance of responsibilities, and how the components ...
- 理解Redux以及如何在项目中的使用
今天我们来聊聊Redux,这篇文章是一个进阶的文章,建议大家先对redux的基础有一定的了解,在这里给大家推荐一下阮一峰老师的文章: http://www.ruanyifeng.com/blog/20 ...
- Redux 中间件的执行顺序理解
Redux.applyMiddleware(thunk, middleware1) 和 Redux.applyMiddleware(middleware1, thunk) 的区别: <!DOCT ...
- 【React】360- 完全理解 redux(从零实现一个 redux)
点击上方"前端自习课"关注,学习起来~ 前言 记得开始接触 react 技术栈的时候,最难理解的地方就是 redux.全是新名词:reducer.store.dispatch.mi ...
随机推荐
- 【Foreign】不等式 [数论]
不等式 Time Limit: 10 Sec Memory Limit: 128 MB Description 小z热衷于数学. 今天数学课的内容是解不等式:L<=S*x<=R .小z心 ...
- 【BZOJ4540】【HNOI2016】序列 [莫队][RMQ]
序列 Time Limit: 20 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 给定长度为n的序列:a1,a2,…,a ...
- 【HNOI】 期望面积
[题目描述]给定n个点,求这n个点组成凸包的期望面积.保证任意三点不共线. [数据范围]n<=100. 首先我们知道凸包面积的计算为所有在凸包上相邻的点的叉积和,那么我们可以枚举两个点,然后求出 ...
- 【bug】vue-cli 3.0报错的解决办法
先上bug图片 bug说明:初装vue_cli3.0写了个组件,运行错误,显示如图, 代码提示:[Vue warn]: You are using the runtime-only build of ...
- window对象的方法和属性汇总
window对象有以下方法: open close alert confirm prompt setTimeout clearTimeout setInterval clearInterval mov ...
- CSS浮动为什么不会遮盖同级元素
1.问题描述 在W3CSchool学习web前端时,看完CSS定位-浮动这一节后,感觉没有什么问题.但是在CSS高级-分类这一节的中进行实践时,遇到了如下问题.测试地址:浮动的简单应用. 完整的htm ...
- .net XmlHelper xml帮助类
using System.Data; using System.IO; using System.Xml; using System.Xml.Serialization; /// <summar ...
- 设计模式之Prototype
设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 为什么要用Prototype ...
- spring mvc 提供的几个常用的扩展点
转载 :http://blog.csdn.net/gufachongyang02/article/details/43836105 这是spring3 mvc的核心流程图: SpirngMVC的第 ...
- 工程化管理--maven
mavne模型 可以看出 maven构件都是由插件支撑的 maven的插件位置在:F:\MavenRepository\org\apache\maven\plugins Maven仓库布局 本地仓库 ...