1、为什么要用reducer去修改数据,直接在state或者store上修改不是更简单吗?

结论是:

  • 1、数据流可控
  • 2、因为数据流只能函数调用(dispatch对应等reducer)修改state,所以把修改数据局限在一定的范围,不像之前可以随意 更改对象的属性和值,这也是面向对象的一个思想,封装,不能谁都能对你的对象有操作权限,防止轻易的修改数据
  • 3、基于第二点,函数的调用就会产生函数调用栈,而直接修改对象是不会有这个栈的,所以可以在reducer里面打断点,或者console,看看谁调用了自己,从而排查出异常的修改

2、实现一个单一store的createstore函数,解释逻辑

  1. function createStore (state, stateChanger) {
  2. const listeners = []
  3. const subscribe = (listener) => listeners.push(listener)
  4. const getState = () => state
  5. const dispatch = (action) => {
  6. state = stateChanger(state, action) // 覆盖原对象
  7. listeners.forEach((listener) => listener())
  8. }
  9. dispatch({})
  10. return { getState, dispatch, subscribe }
  11. }

就上面代码举个例子大家就知道逻辑了

  1. // 按照我们平时写reducer的写法,写一个简单的reducer
  2. const reducer = function(state={a:2}, action){
  3. switch (action.type) {
  4. case 'A':
  5. return { ...state, a: 5 }
  6. default:
  7. return state;
  8. }
  9. }
  10. // 接着我们create一个store
  11. const store = createStore(null, reducer)
  12. // 这里注意,我们没有传state,我们在createStore代码里有一条dispatch({})
  13. // 因此就初始化了state
  14. store.getState() // 获取初始化后的state
  15. store.dispatch({ type: 'A' }) // 使用dispatch来更新state
  16. store.subscribe(() => {
  17. //更新视图的逻辑
  18. })