该项目使用了koa2 + react + react-router(4.0) + redux + webpack等流行技术,在项目中记录的一些知识点和爬坑笔记。
比如对redux的数据流的理解,react-router 4.0.0 的新语法等详细可以去项目中看。
github地址: https://github.com/dlyt/react-koa-login
效果图
下面介绍一下redux-thunk
这是登录的action /src/client/actions/authActions.js
export function login(user) {
return dispatch => {
return axios.post('/api/auth', user).then(res => {
const token = res.data.token
localStorage.setItem('jwtToken', token)
setAuthorizationToken(token)
dispatch(setCurrentUser(jwtDecode(token)))
})
}
}
如果不添加 redux-thunk 这个中间件这段代码是会保错的,提示如下:
Actions must be plain objects. Use custom middleware for async actions.
这里,要先知道:
通过使用指定的 middleware,action 创建函数除了返回 action 对象外还可以返回函数。这时,这个 action 创建函数就成为了 thunk。
下面的代码更容易我们理解(https://medium.com/@WendellLiu/送讓你的action能作更多-redux-thunk-c07bc5488e48)
const foo = () => {
let bar = 'before'
setTimeout(() => {
bar = 'after'
}, 3000)
return {
bar
}
}
document.getElementById('demo').innerHTML = foo().bar
由于 foo 中回传的 bar 在 return 之时是为 ‘before’ ,并不会等到 setTimeout 结束后在被 assign 的 ‘after’。
再来理解一下这句话:
如果不引入 thunk 它只有同步操作。每当 dispatch action 时,state 会被立即更新。这时候使用异步操作就会报错。
我们解决这个问题就可以使用 redux-thunk ,它是通过中间件(middleware)的形式被引用。
这句话有助于你理解 middleware: 它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。
middleware 改造了你的 dispatch ,让它有能力判断送进去的东西是一个 pure object 还是 function 。
我们先看一下 redux-thunk 是如何使用的。
import thunkMiddleware from 'redux-thunk'
const store = createStore(
reducers,
compose(
applyMiddleware(
thunkMiddleware, // 允许我们 dispatch() 函数
loggerMiddleware // 一个很便捷的 middleware,用来打印 action 日志
),
)
)
redux-thunk 的源码中,首先判断是否是 function :
if (typeof action === 'function'){}
如果不是 function ,那自然就是一个 pure object ,利用 next 送出,什么也不需要做;若是 function ,则把这个 thunk 需要的 dispatch , getState 和其他 arguement 传给 thunk ,让它做你所指定它做的事情。
redux-logger 这个中间件会在控制台打印出 action 如图,有助于开发。
以上内容很多都是摘抄的,我根据在项目中遇到的问题,整理总结。