简介

Redux createStore 模拟实现学习笔记。

createStore 模拟实现

/**
 * [createStore 创建 store 应用程序]
 * @param  {[Function]} reducer      [纯函数:封装成修改应用状态的 dispatch 方法]
 * @return {[Object]}                [返回一个对象:包含三个方法 getState、dispatch、subscribe]
 */
function createStore(reducer) {
  let state = null;
  const listeners = [];
  /*一、数据修改后自动执行的订阅函数*/
  const subscribe = (listener) => listeners.push(listener);
  /*二、获取应用状态数据*/
  const getState = () => state;
  /*三、修改应用状态数据*/
  const dispatch = (action) => {
    /*1、修改应用程序的状态:传入当前 state -> 生成新的 state -> 覆盖原对象*/
    state = reducer(state, action);
    /*2、应用程序的状态修改后,自动执行的订阅函数*/
    listeners.forEach((listener) => listener());
  };
  dispatch({});
  return { getState, dispatch, subscribe };
}

createStore 初始化应用状态

/*创建 store 应用程序*/
const store = createStore(reducer);
/*缓存旧的 state*/
let oldState = store.getState();
/*应用程序状态修改后:执行订阅函数*/
store.subscribe(() => {
  /*渲染前:应用程序最新 state*/
  const newState = store.getState();
  /*执行订阅函数*/
  renderApp(newState, oldState);
  /*渲染后:将新的 state 置为旧的 state*/
  oldState = newState;
});

reducer 修改应用状态

/**
 * [reducer 纯函数:修改应用状态的专用方法 -> 通过 createStore 方法包转成 dispatch 函数]
 * @param  {[Object]} state  [应用状态]
 * @param  {[Object]} action [修改应用状态的指令:包括 type 和 payload]
 * @return {[Object]}        [返回最新的应用状态]
 */
function reducer(state, action) {
  /*应用初始状态*/
  if (!state) {
    return {
      title: {
        text: 'title',
        color: 'red',
      },
      content: {
        text: 'content',
        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;
  }
}

页面首次渲染

/**
 * [renderApp 主渲染函数]
 * @param  {[Object]} newAppState [最新应用状态]
 * @param  {[Object]} oldAppState [上一次应用状态]
 */
function renderApp(newAppState, oldAppState = {}) {
  /*数据没有变化就不渲染了*/
  if (newAppState === oldAppState) return;
  console.log('render app...');
  renderTitle(newAppState.title, oldAppState.title);
  renderContent(newAppState.content, oldAppState.content);
}
/**
 * [renderTitle 渲染 title]
 * @param  {[Object]} newTitle [最新 title]
 * @param  {[Object]} oldTitle [上一次 title]
 */
function renderTitle(newTitle, oldTitle = {}) {
  /*数据没有变化就不渲染了*/
  if (newTitle === oldTitle) return;
  console.log('render title...');
  const titleDOM = document.getElementById('title');
  titleDOM.innerHTML = newTitle.text;
  titleDOM.style.color = newTitle.color;
}
/**
 * [renderContent 渲染 content ]
 * @param  {[Object]} newContent [最新 content]
 * @param  {[Object]} oldContent [上一次 content]
 */
function renderContent(newContent, oldContent = {}) {
  /*数据没有变化就不渲染了*/
  if (newContent === oldContent) return;
  console.log('render content...');
  const contentDOM = document.getElementById('content');
  contentDOM.innerHTML = newContent.text;
  contentDOM.style.color = newContent.color;
}

/*首次渲染页面*/
renderApp(store.getState());

修改状态后渲染

/*修改标题文本*/
store.dispatch({ type: 'UPDATE_TITLE_TEXT', text: 'new title' });
/*修改标题颜色*/
store.dispatch({ type: 'UPDATE_TITLE_COLOR', color: 'blue' });

源码阅读

地址: https://github.com/yunaichun/react-study

参考资料

powered by Gitbook该文件修订时间: 2023-05-16 18:08:03

results matching ""

    No results matching ""