Redux 深入理解 (2)

Duang2017-12-01 12:44:56前端基础JavaScriptReact

提示

在理解了 redux 的作用原理后,我们来看看 redux 的基本概念。

state

state:state 是状态管理的根本。在 redux 中,有唯一的状态树 state,为整个应用共享。本质上是一个普通对象。处于程序逻辑中,无法直接调用。

store

store:store 是 state 的管理者,一个应用同样只有唯一的 store,管理着唯一的 state。store 包含下列四个函数:

getState() :用于获取整个 state

dispatch(action) :View 触发 action 改变 state 的唯一途径,请注意我用了唯一这个词

subscribe(listener) :可以理解成是 DOM 中的 addEventListener ,也就是我在上一篇里说过的发布订阅模式中的订阅方法,在 redux 的使用中,这个方法通常不需要手动使用,一般会放在 setState 方法中。

replaceReducer(nextReducer) :这个不太常用,一般在 Webpack Code-Splitting 按需加载的时候用获取 state 的方式:

这几个方法中,dispatch函数略微难理解一点,单独提出来说说。

dispatch

dispatch(action)用于 View 层想要更改 state 的操作,发布订阅模式中的发布操作。用于通知 store 做相应变更。

那么怎么让 store 知道变更哪一个属性呢?这里就要提到action了。action实际上是一个包含了type属性以及payload对象属性(这个叫载荷,不是必须的,但是在规范里推荐使用)的普通对象。其中type属性定义了应该进行的操作名。

我们从这里可以看出,由于载荷的存在,通常我们需要对action进行一些处理,因此,通常action对象由一个返回action对象的普通函数生成,一般我们称之为actionCreator函数。

actionCreator函数不仅可以直接返回action对象,也可以返回一个闭包,闭包传入的参数可以为我们刚才介绍的 store 中的四个函数,最终结果必须返回一个action对象。

注:actionCreator函数不能直接当做参数传入 dispatch 中,必须引入中间件redux-thunk

createStore

于是问题来了,既然state是由store生成和管理的,那么这个store又是怎么来的呢?生成 store 的方式又需要用到一个新的函数:createStore(reducer, intialState, applyMiddleware)。(initialState参数可以设置初始 state,非必须。applyMiddleware(middlewares)方法用于引入中间件,这里按住不表)这里又引出来一个新东西:reducer,这是干什么的呢?

reducer

刚刚说到的 action ,我的简单的理解是:type 的值就是函数名,payload 的值就是函数的传入参数。那么这个特殊的“函数”在哪里执行呢?redux 的思想是:当 View 层调用dispatch方法,发出相应的actionstorestore 收到 action 以后,必须给出一个新的 state,这样 View 才会发生变化。这种 state 的计算过程就叫做 reducer

reducer(oldState, action)是一个纯函数(指任何时候输入同一个数据,返回的数据永远都相同,也就是说 reducer 函数中的处理不能带有任何异步操作),reducer负责对state操作,接收旧的 state 和 action,根据action.type的类型以及action.payload中的数据,处理 state 并返回。

const reducer = (state, action) => {
  switch (action.type) {
    case 'ADD':
      return {
        ...state,
        count: state.count + action.payload.num;
      }
    case 'DELETE':
      return {
        ...state,
        count: state.count - action.payload.num;
      }
    default:
      return state;
  }
};

一行代码简单来说就是(oldState, action) => newState。由于reducer是直接替换state,因此reducer必须有返回值。不然整个 redux 就会得不到state了。

话说一个计算变化重新生成 state 的方法为什么要叫 reducer 呢?我查了查资料,原来这个方法可以作为数组的reduce方法的参数。使用方法如下:

const actions = [
  { type: 'ADD', payload: {num: 1} },
  { type: 'ADD', payload: {num: 2} }
];

const newState = actions.reduce(reducer, state); // {..., count: 3}

由于 redux 中,reducerstate一样,也是唯一的,因此如果我们需要根据不同的处理逻辑分割reducer的话,需要用combineReducers({reducer})将这些reducer合并成一个rootReducer

最后更新时间 2/7/2025, 12:13:03 PM
Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v2.15.8