redux入门 | 青训营

55 阅读3分钟

Redux

Redux 是一个使用叫作 "actions" 的事件去管理和更新应用状态的模式和工具库。 它以集中式 Store(centralized store)的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。

基础概念

store:保存全局 state 的容器

不能直接修改保存至store中的state,必须通过创建一个描述状态发生了什么变化的 action 对象并通过 dispatch 将其派发给store,store会调用 reducer 方法,根据action 和旧的state计算新值,store 会通知 订阅者 state 发生变化,更新UI

  • store.getState() 方法获取当前state
  • store.subscribe()方法订阅
  • store.dispatch()方法派发action

action :具有 type 字段的普通 JavaScript 对象,描述应用程序中发生了什么的事件.

  • type 字段: action 的一个描述性的名字,通常写成“域/事件名称”,其中第一部分是这个 action 所属的特征或类别,第二部分是发生的具体事件
  • payload 字段:action相关事件的附加信息

reducer :根据接收到的action进行处理的纯函数

接收当前的 state 和一个描述发生了什么的 action 对象,必要时决定如何更新状态,并返回新状态的一个函数

  • 函数签名:(state, action) => newState
  • 仅使用 state 和 action 参数计算新的状态值;禁止直接修改 state。必须通过复制现有的 state 并对复制的值进行更改的方式来做 不可变更新
  • 禁止任何异步逻辑、依赖随机值或导致其他“副作用”的代码

使用示例

// 初始状态
const initialState = { value: 0 }

// reducer函数
function counterReducer(state = initialState, action) {
  if (action.type === 'counter/increment') {
    return {
			// 使用拓展操作符创建一个state的副本
      ...state,
      // 使用新值更新 state 副本
      value: state.value + 1
    }
  }
  // 返回原来的 state 不变
  return state
}
// Redux.createStore方法中传入一个reducer对象,创建store 
const store = Redux.createStore(counterReducer)

// store.getState方法获得当前的state值 value:0
store.getState()

// store.dispatch()传入action,派发给store
store.dispatch({ type: 'counter/incremented' })

// 更新后value:1
store.getState()

目前能够实现上述概念中提到的redux运转的完整流程,声明一个reducer函数对于state如何变化进行处理,将该reducer函数作为参数创建一个store,能够通过store.dispatch方法派发一个state变化的action,store将更新state,可通过store.getState方法获取到新的state值;但是该过程还没有和UI绑定,假设有如下一段HTML结构,我们要想在点击button时更新上面显示的内容,该怎么做呢

...
<div>
      <p>
        Clicked: <span id="value">0</span> times
        <button id="increment">+</button>
      </p>
</div>

// 获取id为value的元素
const valueEl = document.getElementById("value");

// 将该元素的值与store中的值绑定
function render() {
	const state = store.getState();
  valueEl.innerHTML = state.value.toString();
}
render();

// 订阅该render函数,当store中状态发生变化时,调用并更新元素展示的值     
store.subscribe(render);

// 绑定点击事件,当点击时触发store.dispatch方法,发生一个action
document.getElementById("increment").addEventListener("click", function () {
          store.dispatch({ type: "counter/incremented" });
});

通过上述方法则在实现了redux的一个简单应用,《基础概念》章节提到的概念都得到了应用,相信已经对整个redux的过程有了全面的了解。但是在我们的日常开发中已经很少手写这些DOM的操作方法,UI和数据通过react实现绑定并更新。如何在react中使用redux进行数据管理呢?明天将展示如何通过Redux-Toolkit和react实现一个简单的todolist案例实践