小菜鸟的React之路--Redux基础2

799
本系列文章主要整理于书籍《React状态管理与同构实战》,属于读书笔记。
本文推荐读者:菜鸟前端,初学前端者。
本文是系列文章第二篇,主要讲述的是如何构建一个简单的,十分基础的 Redux,以及每一步大概是做什么的,希望会对读者有一丢丢帮助。

4、 Redux 基本使用和实践

4.1 构造store

​ store 保存着整个状态数据库,是 Redux 中核心,里面保存许多重要的API。

store = {
    dispatch,
    getState,
    subscribe,
    replaceReducer,// 暂时用不到所以暂时忽略
}

​ 这些方法的使用:

  • dispatch(action) : 派发 action
  • subscribe(listener): 订阅页面数据的状态, 即 store 中 state 的变化
  • getState: 获取状态数据树,即 store 中的 state 状态

​ 当我们引入 Redux 之后,就可以通过方法 Redux.createStore 创建页面应用的 store

import { createStore } from 'redux';
const store = createStore( reducer, preloadedState, enhancer )
  • reducer: 开发者自己编写的 reducer 函数,必选
  • preloadedState: 页面状态数据树的初始状态,可选
  • ehhancer: 增强器,函数类型,可选

​ reducer 函数是创建 store 时候必填的参数,所以我们需要在此之前就设计好 reducer 函数,用来告知 store 数据状态是如何根据 action 进行变更的。

4.2 构造 action

  • action 描述了状态变更的信息,也就是需要页面做出的变化。
  • action 本质上是一个 JS 对象,根据 Redux 的规定,action 需要包含以下内容:
    • type属性: 作为 action 的名称,用来识别当前 action ,相当于 action 的身份证(暂时理解为身份证中的国籍,姓名等非单一性的属性,因为 type 可以是一类对象,而不仅仅只有一个),一般是 string 类型。
    • action 的一些数据信息,主要包括了这个 action 变化的基本内容。
const action = {
    type: 'READ_BOOK',
    data: {
        name: '你不知道的JS'
    }
}
// 这里面的 action.type 可以表述为,’读书‘。读的是什么书? action.data.name:'你不知道的JS'

4.3 使用 action create (构造器)

​ 存在如下场景:当用户进行书籍推荐的时候,我们就要生产一个 type: 'READ_BOOK' 的 action,但是这些 action 尽管数据有差别,但是他们的 type 都是一样的,所以我们可以创建一个函数来构造这些 type 一样的 action。

const createSameTypeAction = (na'me) => {
    type: 'READ_BOOK',
    name
}

4.4 使用 dispatch 派发 action

​ dispatch 就是 store 对象中暴露出来的方法属性,可以直接调用来派发 action 。

store.dispatch(createSameTypeAction('node.js 实战'))

4.5 编写 reducer 函数更新数据

  • action 描述了一种变化,并且携带了这种变化的一些相关信息,而真正将这种变化落实,生成正确的数据状态的,是 reducer 函数。
  • reducer 函数必须是纯函数,目的是保证数据变化的可预测性(可以查看第三节)
const updateStateTree = (preState={},action) => {
    switch(action.type){
        case:'case1':
        	return newState1;
        case:'case2':
        	return newState2
        default:
            return preState // 当所有action都不匹配时,返回默认的状态
    }
}

4.6 基本使用小结

  • 当通过 Redux 的 createState 方法创建出一个 store 实例后,就可以使用 store.dispatch(action) 来派发一个描述变化的 action 。
  • 在执行 store.dispatch 之后, Redux 会‘自动’执行处理 store 并更新数据的 reducer 函数。
  • 具体的数据变化对象 action 和数据处理函数 reducer 需要开发人员根据具体业务进行编写。
  • reducer 函数处理结束后,数据发生了改变,此时页面通过 store.subscribe(callbackFunction)方法订阅数据的更新,根据给定的回调函数 callbackFunction 进行页面的更新。

4.7 合理拆分 reducer 函数

​ 当业务变复杂时,可能需要很多 action 来描述不同的变化,此时如果仍然使用一般的 reducer 函数,就会显得很大而且难以维护,所以 Redux 提供了一个 conbineReducers 的工具函数,用来对拆分 reducer 函数重新合并成一个完整的 reducer。

// 当一个业务需要更改多个数据时,可以根据数据状态进行拆分
state = {
    data1:{...},
    data2:{...},
    data3:{...},
};
           
const reducer1 = ( preState={}, action ){
  // 根据 action 和 state.data1 计算出新的 state.data1
  return state1.data1
};
const reducer2 = ( preState={}, action ){
  // 根据 action 和 state.data2 计算出新的 state.data2
  return state1.data2
};
const reducer3 = ( preState={}, action ){
  // 根据 action 和 state.data3 计算出新的 state.data3
  return state1.data3
}

const { combineReducers } = Redux
const finalReducer = combineReducers({
    data1: reducer1,
    data2: reducer2,
    data3: reducer3,
})