<Redux>实现MyRedux(三)

实现MyRedux系列

  1. 实现MyRedux(一)
  2. 实现MyRedux(二)
  3. 实现MyRedux(三)

现在通过前边两部分,我们实现了一个通用的createStore

function createStore (state, stateChanger) {
  const listeners = []
  const subscribe = (listener) => listeners.push(listener)
  const getState = () => state
  const dispatch = (action) => {
    state = stateChanger(state, action) // 覆盖原对象
    listeners.forEach((listener) => listener())
  }
  return { getState, dispatch, subscribe }
}

那他怎么用呢?

let appState = {
  title: {
    text: 'React.js',
    color: 'red',
  },
  content: {
    text: 'React.js 内容',
    color: 'blue'
  }
}

function stateChanger (state, action) {
  switch (action.type) {
    case 'UPDATE_TITLE_TEXT':
      return {
        ...state,
        title: {
          ...state.title,
          text: action.text
        }
      }
    case 'UPDATE_TITLE_COLOR':
      return {
        ...state,
        title: {
          ...state.title,
          color: action.color
        }
      }
    default:
      return state
  }
}

const store = createStore(appState, stateChanger)
...

其实可以优化一下,appStorestateChange可以合并

function stateChanger (state, action) {
  if (!state) {
    return {
      title: {
        text: 'React.js',
        color: 'red',
      },
      content: {
        text: 'React.js 内容',
        color: 'blue'
      }
    }
  }
  switch (action.type) {
    case 'UPDATE_TITLE_TEXT':
      return {
        ...state,
        title: {
          ...state.title,
          text: action.text
        }
      }
    case 'UPDATE_TITLE_COLOR':
      return {
        ...state,
        title: {
          ...state.title,
          color: action.color
        }
      }
    default:
      return state
  }
}

stateChange现在既充当了获取初始化数据的功能,也充当了生成更新数据的功能,如果传入了state就更新数据,否则为初始化数据,那createStore可以优化成一个参数,因为statestateChange可以合并

function createStore (stateChanger) {
  let state = null
  const listeners = []
  const subscribe = (listener) => listeners.push(listener)
  const getState = () => state
  const dispatch = (action) => {
    state = stateChanger(state, action)
    listeners.forEach((listener) => listener())
  }
  dispatch({}) // 初始化 state
  return { getState, dispatch, subscribe }
}

createStore 内部的 state 不再通过参数传入,而是一个局部变量 let state = nullcreateStore 的最后会手动调用一次 dispatch({})dispatch 内部会调用 stateChanger,这时候的 statenull,所以这次的 dispatch 其实就是初始化数据了。createStore 内部第一次的 dispatch 导致 state 初始化完成,后续外部的 dispatch 就是修改数据的行为了。

stateChange可以换一个名字,就叫他reducer,不要问,问就是reducer

function createStore (reducer) {
  let state = null
  const listeners = []
  const subscribe = (listener) => listeners.push(listener)
  const getState = () => state
  const dispatch = (action) => {
    state = reducer(state, action)
    listeners.forEach((listener) => listener())
  }
  dispatch({}) // 初始化 state
  return { getState, dispatch, subscribe }
}

reducer

createStore接受一个叫reducer的函数,他一定是一个纯函数,他接收两个参数,一个是state,一个是action

他不能干任何事情,只能初始化和计算新的state


总结

从第一篇开始,首先发现如果共享的状态能被随意修改,那程序地行为会不可预料,所以我们要求只能通过dispatch去进行数据修改,而且必须要在action中声明,然后我们把它抽象出来成为一个createStore,它能生产store,里面有getStatedispatch让我们使用

后来发现每次修改数据都要重新渲染,而我们希望能够自动渲染视图,所以使用了订阅者模式,通过store.subscribe订阅数据修改事件,为了让它自动渲染视图

在我们使用的时候发现每次都重新渲染视图会有很大的性能问题,所以使用共享结构的对象来解决问题,而后让stateChanger更名为reducer,并让他是一个纯函数,负责初始化state,根据stateaction计算具有共享结构的新state


在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值