先来看一下 Redux, 以及 react-redux 工作流程图
通过这张流程图, 我们可以更好的理解 Redux 和 React 直接数据如何流通, 关系如何映射.
让我们一步步来了解图中的各个概念.
#####action & actionCreator
action creator 就是函数而已, 负责构建一个 action (是的, action creator 这个名字已经很明显了)并返回它. 通过几行简单的代码就可以解释清楚了!
JavaScript 代码
- const actionCreator = function () {
- return {
- type : 'AN_ACTION'
- }
- }
一般约定 action 是一个拥有 type 属性的对象.
JavaScript 代码
- console.log(actionCreator())
- // {
- type: 'AN_ACTION'
- }
- reducer
Reducer 函数只是一个纯函数, 它接收应用程序的当前状态以及发生的 action, 然后返回修改后的新状态(或者有人称之为归并后的状态).Reducer 函数是 action 的订阅者.
JavaScript 代码
- const reducer = function (state = {}, action) {
- console.log('reducer was called with state', state, 'and action', action);
- return state;
- }
- Store
以上, action 描述 "发生了什么", 而 reducer 根据 action 来更新 state. 但是他们两者之间是如何关联的呢?
不用担心, Redux 会帮你把 action 和 reducer 连接起来.
我们把 Redux 实例称为 store 并用以下方式创建:
JavaScript 代码
- import {
- createStore
- } from 'redux'
- const store_0 = createStore(() => {
- })
注意: 在 createStore 时, 需要给它传入一个 reducer 函数.
每当一个 action 发生时, Redux 都能调用这个函数. 往 createStore 传 Reducer 的过程就是给 Redux 绑定 action 处理函数 (也就是 Reducer) 的过程.
接下来, 试着在 Reducer 中打印一些 log
JavaScript 代码
- const reducer = function (...args) {
- console.log('Reducer was called with args', args)
- }
- const store_1 = createStore(reducer)
- // 输出: Reducer was called with args [ undefined, { type: '@@redux/INIT' } ]
我们没有 dispatch(分发)任何 action, 但是 reducer 被调用了! 这是由于初始化应用 state 的时候, Redux dispatch 了一个初始化的 action ({ type: '@@redux/INIT' }).reducer 的入参为(state, action).state 还没有被初始化, 自然为 undefined.
如何读取 store 中的 state?
Redux 为我们提供了 store.getState()方法.
JavaScript 代码
- import { createStore } from 'redux'
- const reducer_2 = function (state = {}, action) {
- console.log('reducer_2 was called with state', state, 'and action', action)
- return state;
- }
- const store_2 = createStore(reducer_2)
- // 输出: reducer_2 was called with state {} and action { type: '@@redux/INIT' }
- console.log('store_2 state after initialization:', store_2.getState())
- // 输出: store_2 state after initialization: {}
如何 dispatch action?
我们需要使用 store.dispatch(action)方法.
JavaScript 代码
- // 接以上代码
- const anAction = {
- type : 'AN_ACTION'
- }
- store_2.dispatch(anAction);
- // 输出: reducer_2 was called with state {} and action { type: 'AN_ACTION' }
- #####combineReducers
combineReducer 用于合并 Reducers, 并且合并对应的 State.
JavaScript 代码
- const userReducer = function (state = {}, action) {
- console.log('userReducer was called with state', state, 'and action', action)
- switch (action.type) {
- // etc.
- default:
- return state;
- }
- }
- const itemsReducer = function (state = [], action) {
- console.log('itemsReducer was called with state', state, 'and action', action)
- switch (action.type) {
- // etc.
- default:
- return state;
- }
- }
- import { createStore, combineReducers } from 'redux'
- const reducer = combineReducers({
- user : userReducer,
- items : itemsReducer
- })
- // 输出:
- // userReducer was called with state {} and action { type: '@@redux/INIT' }
- // userReducer was called with state {} and action { type: '@@redux/PROBE_UNKNOWN_ACTION_9.r.k.r.i.c.n.m.i' }
- // itemsReducer was called with state [] and action { type: '@@redux/INIT' }
- // itemsReducer was called with state [] and action { type: '@@redux/PROBE_UNKNOWN_ACTION_4.f.i.z.l.3.7.s.y.v.i' }
- var store_0 = createStore(reducer)
- // 输出:
- // userReducer was called with state {} and action { type: '@@redux/INIT' }
- // itemsReducer was called with state [] and action { type: '@@redux/INIT' }
- console.log('store_0 state after initialization:', store_0.getState())
- // 输出:
- // store_0 state after initialization: { user: {}, items: [] }
回过头来看看文章开头的数据流向图
View 组件通过 click 等事件, dispatch 一个(actionCreator 返回的)action, 通过 Store 把当前状态 state 和 action 传递给订阅者 reducer 函数, reducer 返回一个新的状态存储在 Store 中, Store 又把新的 State 传递给 View 组件触发组件更新.
为了将 Redux 和 React 联系到一起. 就需要用到 React-Redux 这个库.
JavaScript 代码
- import {
- connect
- } from 'react-redux'
- const containerComponent = connect(mapStateToProps, mapDispatchToProps)(presentationalComponent)
简单来说, mapStateToProps 和 mapDispatchToProps 就是分别把 Redux 的 state, 和 dispatch(action)映射到 React 组件中作为 props.connect 将展示组件 (presentationalComponent) 封装成高阶的容器组件(containerComponent).state 的更新意味着 props 更新.
如果对整个流程还不太清楚的, 可以去看阮老师的三篇关于 redux 的文章, 也是非常的详细.
来源: http://www.qdfuns.com/article/23231/de92e9e00943a9ac9609aaca5cd7f181.html