介绍Redux

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。

动机

我们现在管理不断变化的 state 非常困难。如果一个 model 的变化会引起另一个 model 变化,那么当 view 变化时,就可能引起对应 model 以及另一个 model 的变化,依次地,可能会引起另一个 view 的变化。直至你搞不清楚到底发生了什么。state 在什么时候,由于什么原因,如何变化已然不受控制。 当系统变得错综复杂的时候,想重现问题或者添加新功能就会变得举步维艰。Redux就是为了帮你解决这个问题。

Redux的核心理念 - Store

  1. Redux的核心理念非常简单。
  2. 如果我们没有定义统一的规范来操作这段数据,那么整个数据的变化就是无法跟踪的
  3. 比如页面的某处通过products.push的方式增加了一条数据
  4. 比如另一个页面通过products[0].age = 25修改了一条数据
  5. 整个应用程序错综复杂,当出现bug时,很难跟踪到底哪里发生的变化

Redux的核心理念 - action

  1. Redux要求我们通过action来更新数据
  2. 所有数据的变化,必须通过派发(dispatch)action来更新
  3. action是一个普通的JavaScript对象,用来描述这次更新的type和content
  4. 强制使用action的好处是可以清晰的知道数据到底发生了什么样的变化,所有的数据变化都是可跟追、可预测的;

下面几个就是需要更新的action

// actions
const action1 = { type: "INCREMENT" };
const action2 = { type: "DECREMENT" };

const action3 = { type: "ADD_NUMBER", num: 5 };
const action4 = { type: "SUB_NUMBER", num: 12 };


Redux的核心理念 - reducer

上面我们讲了action和store,但是怎么将两者进行连接呢,这是就需要我们的reducer。

  1. reducer是一个纯函数
  2. reducer做的事情就是将传入的state和action结合起来生成一个新的state;
// reducer
function reducer(state = initialState, action) {
  switch (action.type) {
    case "INCREMENT":
      console.log({ ...state, counter: state.counter + 1 });
      return { ...state, counter: state.counter + 1 }
    case "DECREMENT":
      return { ...state, counter: state.counter - 1 }
    case "ADD_NUMBER":
      return { ...state, counter: state.counter + action.num }
    case "SUB_NUMBER":
      return { ...state, counter: state.counter - action.num }
    default:
      return state;
  }
}

Redux的三大原则

  1. 单一数据源
    整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
  2. State 是只读的
    唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
  3. 使用纯函数来执行修改
    为了描述 action 如何改变 state tree ,你需要编写 reducers。

Redux使用流程

e04ef5825429d70e0e942f7f2e7d504b.jpg
来自coderwhy老师的github的图片

整段代码

// 1.导入redux(不能通过ES6的方式)

// import/export 13.2.0开始支持

// commonjs一种实现 -> nodejs
const redux = require('redux');

const initialState = {
  counter: 0
}

// reducer
function reducer(state = initialState, action) {
  switch (action.type) {
    case "INCREMENT":
      console.log({ ...state, counter: state.counter + 1 });
      return { ...state, counter: state.counter + 1 }
    case "DECREMENT":
      return { ...state, counter: state.counter - 1 }
    case "ADD_NUMBER":
      return { ...state, counter: state.counter + action.num }
    case "SUB_NUMBER":
      return { ...state, counter: state.counter - action.num }
    default:
      return state;
  }
}

// store(创建的时候需要传入一个re ducer)
const store = redux.createStore(reducer)

// 订阅store的修改
store.subscribe(() => {
  console.log("counter:", store.getState().counter);
})

// actions
const action1 = { type: "INCREMENT" };
const action2 = { type: "DECREMENT" };

const action3 = { type: "ADD_NUMBER", num: 5 };
const action4 = { type: "SUB_NUMBER", num: 12 };

// 派发action
store.dispatch(action1);
store.dispatch(action2);
store.dispatch(action2);
store.dispatch(action3);
store.dispatch(action4);



Q.E.D.