Koa2 + react 实现一个登录Demo,附redux-thunk详解。

#1

该项目使用了koa2 + react + react-router(4.0) + redux + webpack等流行技术,在项目中记录的一些知识点和爬坑笔记。

比如对redux的数据流的理解,react-router 4.0.0 的新语法等详细可以去项目中看。
github地址: https://github.com/dlyt/react-koa-login
效果图
Octicons

下面介绍一下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 如图,有助于开发。

以上内容很多都是摘抄的,我根据在项目中遇到的问题,整理总结。