前面我们聊了 Redux
的基础概念以及异步解决方案,现在我们来聊聊 Redux
的一些基础 API
,还有相关的一些使用。
在这些 API
中又分为了 Store
上的 API
和其他顶级暴露的一些 API
,请容我一个一个的介绍:
Store API
createStore(reducer, [preloadedState], [enhancer])
创建一个包含程序完整 state 树的 Redux store。
- reducer
- [
preloadedState
]:初始时的 state。如果你使用combineReducers
创建reducer
,它必须是一个普通对象,与传入的 keys 保持同样的结构。否则,你可以自由传入任何reducer
可理解的内容。 - enhancer:用来放中间件
Tips
- 应用中不要创建多个 store!
- Redux state 通常是普通 JS 对象或者数组。
- 如果 state 是普通对象,不要修改它!不可变更新需要复制每个级别的数据,通常使用对象扩展运算符(
return { ...state, ...newData }
)。 - 对于服务端运行的同构应用,为每一个请求创建一个 store 实例,以此让 store 相隔离。dispatch 一系列请求数据的 action 到 store 实例上,等待请求完成后再在服务端渲染应用。
subAPIs
getState()
:返回应用当前的 state 树。 它与 store 的最后一个 reducer 返回值相同。dispatch(action)
:将使用当前getState()
的结果和传入的action
以同步方式的调用 store 的 reducer 函数。它的返回值会被作为下一个 state。从现在开始,这就成为了getState()
的返回值,同时变化监听器(change listener)会被触发。subscribe(listener)
:这是一个底层 API。多数情况下,你不会直接使用它,会使用一些 React(或其它库)的绑定。如果你想让回调函数执行的时候使用当前的 state,你可以 写一个定制的observeStore
工具。Store
也是一个Observable
, 所以你可以使用 RxJS 的这样的库来subscribe
订阅更新。replaceReducer(nextReducer)
:替换 store 当前用来计算 state 的 reducer。
其他顶层 API
combineReducers(reducers)
combineReducers
辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用createStore
方法。
Tips:
- 在 reducer 层级的任何一级都可以调用
combineReducers
。并不是一定要在最外层。实际上,你可以把一些复杂的子 reducer 拆分成单独的孙子级 reducer,甚至更多层。
applyMiddleware(...middleware)
使用包含自定义功能的 middleware 来扩展 Redux 是一种推荐的方式。Middleware 可以让你包装 store 的
dispatch
方法来达到你想要的目的。同时, middleware 还拥有"可组合"这一关键特性。多个 middleware 可以被组合到一起使用,形成 middleware 链。其中,每个 middleware 都不需要关心链中它前后的 middleware 的任何信息。Middleware 最常见的使用场景是无需引用大量代码或依赖类似 Rx 的第三方库实现异步 actions。这种方式可以让你像 dispatch 一般的 actions 那样 dispatch 异步 actions。
Tips:
- Middleware 只是包装了 store 的
dispatch
方法。技术上讲,任何 middleware 能做的事情,都可能通过手动包装dispatch
调用来实现,但是放在同一个地方统一管理会使整个项目的扩展变的容易得多。参考第二篇文章末尾的"我们一定需要Redux-thunk吗" - 如果除了
applyMiddleware
,你还用了其它 store enhancer,一定要把applyMiddleware
放到组合链的前面,因为 middleware 可能会包含异步操作。比如,它应该在 redux-devtools 前面,否则 DevTools 就看不到 Promise middleware 里 dispatch 的 action 了。 - 想要使用多个 store enhancer,可以使用
compose()
方法。
compose(...functions)
从右到左来组合多个函数。这是函数式编程中的方法,为了方便,被放到了 Redux 里。
当需要把多个 store enhancers 依次执行的时候,需要用到它。
bindActionCreators(actionCreators, dispatch)
惟一会使用到
bindActionCreators
的场景是当你需要把 action creator 往下传到一个组件上,却不想让这个组件觉察到 Redux 的存在,而且不希望把dispatch
或 Redux store 传给它。
一般这个场景是把我们的 dispatch 使用,直接挂在到我们的 props 上,方便我们直接去进行调用。