createStore

createStore传入的reducer会在第一次初始化的时候,自动执行一次。actiontype类似于
image.png

多个action进行合并自动分发-bindActionCreators

参数

  1. actionCreators (_Function_ or _Object_): 一个 action creator,或者一个 valueaction creator 的对象。
  2. dispatch (_Function_): 一个由 Store 实例提供的 dispatch 函数。

    返回值

    (_Function_ or _Object_): 一个与原对象类似的对象,只不过这个对象的 **value** 都是会直接 **dispatch****action creator** 返回的结果的函数。如果传入一个单独的函数作为 actionCreators,那么返回的结果也是一个单独的函数。

Reducer

Reducer是用于改变数据的函数

  1. 一个数据仓库,有且仅有一个reducer,并且通常情况下,一个工程只有一个仓库,因此,一个系统,只有一个reducer
  2. 为了方便管理,通常会将reducer放到单独的文件中。
  3. reducer被调用的时机
    1. 通过store.dispatch,分发了一个action,此时,会调用reducer
    2. 当创建一个store的时候,会调用一次reducer
      1. 可以利用这一点,用reducer初始化状态
      2. 创建仓库时,不传递任何默认状态
      3. 将reducer的参数state设置一个默认值
  4. reducer内部通常使用switch来判断type值
  5. reducer必须是一个没有副作用的纯函数
    1. 为什么需要纯函数
      1. 纯函数有利于测试和调式
      2. 有利于还原数据
      3. 有利于将来和react结合时的优化
    2. 具体要求
      1. 不能改变参数,因此若要让状态变化,必须得到一个新的状态
      2. 不能有异步
      3. 不能对外部环境造成影响
  6. 由于在大中型项目中,操作比较复杂,数据结构也比较复杂,因此,需要对reducer进行细分。
    1. redux提供了方法,可以帮助我们更加方便的合并reducer
    2. combineReducers: 合并reducer,得到一个新的reducer,该新的reducer管理一个对象,该对象中的每一个属性交给对应的reducer管理。

      combineReducers(reducers)

      随着应用变得越来越复杂,可以考虑将 reducer 函数 拆分成多个单独的函数,拆分后的每个函数负责独立管理 state 的一部分。

combineReducers 辅助函数的作用是,把一个由多个不同 reducer 函数作为 valueobject,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore 方法。

合并后的 reducer 可以调用各个子 reducer,并把它们返回的结果合并成一个 state 对象。 由 combineReducers() 返回的 state 对象,会将传入的每个 reducer 返回的 state 按其传递给 combineReducers() 时对应的 key 进行命名

注意

本函数设计的时候有点偏主观,就是为了避免新手犯一些常见错误。也因些我们故意设定一些规则,但如果你自己手动编写根 redcuer 时并不需要遵守这些规则。
每个传入 combineReducers 的 reducer 都需满足以下规则:

  • 所有未匹配到的 action,必须把它接收到的第一个参数也就是那个 state 原封不动返回。
  • 永远不能返回 undefined。当过早 return 时非常容易犯这个错误,为了避免错误扩散,遇到这种情况时 combineReducers 会抛异常。
  • 如果传入的 state 就是 undefined,一定要返回对应 reducer 的初始 state。根据上一条规则,初始 state 禁止使用 undefined。使用 ES6 的默认参数值语法来设置初始 state 很容易,但你也可以手动检查第一个参数是否为 undefined。

虽然 combineReducers 自动帮你检查 reducer 是否符合以上规则,但你也应该牢记,并尽量遵守。即使你通过 Redux.createStore(combineReducers(…), initialState) 指定初始 state,combineReducers 也会尝试通过传递 undefined 的 state 来检测你的 reducer 是否符合规则。因此,即使你在代码中不打算实际接收值为 undefined 的 state,也必须保证你的 reducer 在接收到 undefined 时能够正常工作。

  • 本方法只是起辅助作用!你可以自行实现不同功能的 combineReducers,甚至像实现其它函数一样,明确地写一个根 reducer 函数,用它把子 reducer 手动组装成 state 对象。
  • 在 reducer 层级的任何一级都可以调用 combineReducers。并不是一定要在最外层。实际上,你可以把一些复杂的子 reducer 拆分成单独的孙子级 reducer,甚至更多层。
    1. const userReducer: Reducer<UserState[]> = (
    2. state = initialUserState,
    3. action
    4. ) => {
    5. switch (action.type) {
    6. case ADD_USER:
    7. return [...state, action.payload]
    8. case DELETE_USER:
    9. return state.filter(user => user.id !== action.payload)
    10. case UPDATE_USER:
    11. return state.map(user => {
    12. const { payload } = action
    13. return user.id === payload.id ? { ...user, ...payload } : { ...user }
    14. })
    15. default:
    16. return state
    17. }
    18. }
    19. export default userReducer
    ```typescript import { combineReducers } from ‘redux’ import userReducer from ‘@/store/reducer/userReducer’

const rootReducer = combineReducers({ user: userReducer })

export default rootReducer ```