第 29 天 !
剩~两~天~!
昨天已经把整个 redux 的流程给接起来了,
从 store 读取资料还有用 action 去改变 store , 这些我们大概都展示一次 ,
但是很多操作其实并不局限在本地端,
比较正确来说,
现在所做的一系列这样一步接一步的动作,我们称它为 sync(同步)
,
但总有一些操作是我们不会去等,直接前往下一步动作,但会先设定好操作结束後的相关动作,等它去触发,我们称它为 async(非同步)
,
在 redux
要处理 async
, action
跟 reducer
都不能做这部份处理,
我们必须加入 middleware
,
redux 允许我们在这里处理 async
的相关操作,
那... middleware
会在什麽事後触发呢?
老样子, 这是官方提供的流程图
可以看到当我们的 action
去触发 dispatch
时候,在之前并不会直接进入 reducer
, 而是会先进入 middleware
去跑一遍之後,再进去 reducer,
加入 middleware
後的流程应该是:
那如何加入 middleware
?
第一先选择我们要使用的 middleware
,
就是我们今天要介绍的 redux-thunk
,
先来安装:
yarn add redux-thunk
thunk 的内容很少,
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) =>
(next) =>
(action) => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
....嗯,这就是全部了,
有兴趣可以去 thunk 的 github 上看看,
它其实很简单的去建立了,在 middleware
的 async
操作环境,
看程序码其实可以知道的是,middleware
提供了几个参数,
蛮直白的,
getState
,取得 store
的资料,
next
,代表是的这 action
直接往下一个 middleware
走,假如没有就进去 reducer
,
action
, 当前发送的 action
,
extraArgument
这个是 thunk 2.0
才有的参数,主要一开始设定的时候可以带入额外的参数给 middleware
再来就是 thunk
只是很简单的去判断 action
送进来的是不是 function
,
是的话把 dispatch & getState & extraArgument
带入到这个 function
也就是说要做 sync 就照原样送 action ,
想要做 async 就把 action 用成 function,
再来就是把 thunk 塞入 redux 里,
使用 redux
提供的 applyMiddleware
来把 thunk
塞入 redux
,
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducer';
export default function configureStore() {
return createStore(rootReducer, applyMiddleware(thunk));
}
假如有需要额外塞资讯进去,
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducer';
export default function configureStore(api) {
return createStore(
rootReducer,
applyMiddleware(thunk).withExtraArgument({ api })
);
}
这样 thunk
就进入到 redux
流程里了,
我们试着把 TodoList
的 新增用 thunk
实作
const fakeAsync = payload => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(payload);
}, 3000);
});
};
export const insertToDoThunk = payload => {
return async dispatch => {
const item = await fakeAsync(payload);
dispatch(insertToDoAction(item));
};
};
因为我们没有 api 所以设定一个 fakeAsync
来模拟 async,
那流程是 呼叫 insertToDoThunk
会延迟 3 秒,
之後让 dispatch 执行 insertToDoAction
在 Header component
把 insertToDoAction
换成 insertToDoThunk
结果是:
在 Spring boot 可以使用 Logback 进行配置,系统预设加载日志配置档案 logba...
延续上篇的说明,在 Git 的世界,任何动作对 Git 来说都可以视为一个「修改」的动作。因此这篇要...
未完待续的前端之旅 在这30天我们带到了前端技能树上各种类型的技能,包括基本的 HTML、CSS、J...
前言 介绍 useContext 前,我们必须先认识 Context。 Context 概念有点像是...
WhatsApp 聊天记录消失了? 如何恢复 WhatsApp 照片和信息? 我们都有过 Whats...