Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

动手实现一个redux #48

Open
aermin opened this issue Jul 19, 2018 · 0 comments
Open

动手实现一个redux #48

aermin opened this issue Jul 19, 2018 · 0 comments
Labels

Comments

@aermin
Copy link
Owner

aermin commented Jul 19, 2018

概念

  • 一个app有一个store,一个store管理着一个全局state
  • createStore 传入reducer,返回getState, dispatch, subscribe
  • action是一个至少有type这个键的对象,可以写一个creactActioner 函数去return生成action对象
  • createStore.dispatch(action) 根据action这个对象去更新state
  • dispatch是一个函数,内部有将执行reducer函数
  • reducer也是一个函数,传入state,action, 输出一个新的state . (switch case return….)

demo链接

qq20180719-212609-hd

<div id = 'title'></div>
<input type="button" id = "changeTheme" value="变成蓝色主题">
//实现一个createStore
function createStore(reducer) { // 参数是reducer函数(纯函数)
  let state = null;
  const listeners = [];
  const subscribe = listener => listeners.push(listener); // 观察者模式,订阅一次,每次dispatch时都会执行传入的这个函数
  const getState = () => state;
  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener()); // 订阅监听函数
  };
  dispatch({}); // 初始化 state 也就是执行reducer函数,由于没传state,state被默认值替换( {themeName: 'Red Theme',themeColor: 'red'})
  return { getState, dispatch, subscribe };
}

// 写一个reducer
function themeReducer(state, action) {
  if (!state) {
    return { // 若没传state 则返回一个默认的state对象
      themeName: 'Red Theme',
      themeColor: 'red'
    };
  }
  switch (action.type) {
    case 'UPATE_THEME_NAME':
      return { ...state, themeName: action.themeName };
    case 'UPATE_THEME_COLOR':
      return { ...state, themeColor: action.themeColor };
    default:
      return state;
  }
}

// 把reducer传入createStore 生成 store`
const store = createStore(themeReducer); // 这边也初始化了state

// 渲染页面的代码
function renderApp(state) {
  const titleDOM = document.getElementById('title');
  titleDOM.innerHTML = state.themeName;
  titleDOM.style.color = state.themeColor;
}

// 监听数据变化重新渲染页面
store.subscribe(() => renderApp(store.getState()));// 让每次dispatch时都会执行传入的这个函数,渲染页面

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


// 后面可以随意 dispatch  action了,页面自动更新

//creactActioner  action生成函数
const updateThemeName = () => ({
  type: 'UPATE_THEME_NAME',
  themeName: 'Blue Theme'
});
const updateThemeColor = () => ({
  type: 'UPATE_THEME_COLOR',
  themeColor: 'blue'
});

document.getElementById('changeTheme').onclick = () => {
  store.dispatch(updateThemeName());
  store.dispatch(updateThemeColor());
  //这样也行
  //store.dispatch({ type: 'UPATE_THEME_NAME', themeName: 'Blue Theme' });
  //store.dispatch({ type: 'UPATE_THEME_COLOR', themeColor: 'blue' });
};

参考:react小书

@aermin aermin changed the title 动手实现一个redux 动手用原生js实现一个redux Jul 19, 2018
@aermin aermin changed the title 动手用原生js实现一个redux 动手实现一个redux Jul 19, 2018
@aermin aermin added the react label Oct 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant