函数式编程与Redux

说道函数式编程,JS这边Redux是代表中的代表。

以Redux的reducers函数为例,它是标准的纯函数,这里举个最简单的例子,说明为什么要用纯函数:

首先是源码

unction posts(
  state = {
    isFetching: false,
    didInvalidate: false,
    items: []
  },
  action
) {
  switch (action.type) {
    case INVALIDATE_SUBREDDIT:
      return Object.assign({}, state, {
        didInvalidate: true
      })
    case REQUEST_POSTS:
      return Object.assign({}, state, {
        isFetching: true,
        didInvalidate: false
      })
    case RECEIVE_POSTS:
      return Object.assign({}, state, {
        isFetching: false,
        didInvalidate: false,
        items: action.posts,
        lastUpdated: action.receivedAt
      })
    default:
      return state
  }
}

如果我们不用return,在reducer内修改旧的state变量。变为不纯的函数,是这样的。

  switch (action.type) {
    case INVALIDATE_SUBREDDIT:
      state = Object.assign({}, state, {
        didInvalidate: true
      })
    case REQUEST_POSTS:
      state = Object.assign({}, state, {
        isFetching: true,
        didInvalidate: false
      })
    case RECEIVE_POSTS:
      state = Object.assign({}, state, {
        isFetching: false,
        didInvalidate: false,
        items: action.posts,
        lastUpdated: action.receivedAt
      })
    default:
      return state
  }

在Redux中combineReducers.js中看下redux是如何处理的

    let hasChanged = false
    const nextState = {}
    for (let i = 0; i < finalReducerKeys.length; i++) {
      const key = finalReducerKeys[i]
      const reducer = finalReducers[key]
      const previousStateForKey = state[key]
      const nextStateForKey = reducer(previousStateForKey, action)
      if (typeof nextStateForKey === 'undefined') {
        const errorMessage = getUndefinedStateErrorMessage(key, action)
        throw new Error(errorMessage)
      }
      nextState[key] = nextStateForKey
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    return hasChanged ? nextState : state
  }

这两行

 const nextStateForKey = reducer(previousStateForKey, action)
hasChanged = hasChanged || nextStateForKey !== previousStateForKey

reducer将旧的状态(prev)和要修改的数据一起传进去,然后返回一个新的(next)状态,prev和next相比较来确定storge数据是否改变。如果我们用不纯的函数,prev和next将一致,就算数据改变,hasChanged也会是false。通过函数式的方式没有什么“副作用”

Redux全篇都是函数式编程,这里只是冰山一角。Redux的源码写得非常优雅。

END

読んでくれてありがとう~