/*
* @authored by Chris
* 功能:不用每次全部渲染(renderTitle和render Content),根据相应的变化,从而提高性能。
* 先实例化store,传入初始的state=appState以及stateChanger
* 调用store.subscribe将 const newState = store.getState();
renderApp(newState,oldState);
oldState = newState;
注册成监听器,以供每次dispatch时执行
*调用dispatch,根据action参数,做相应的数据变化,随后执行监听器(监听器使得页面重新渲染,从而让新的数据呈现在页面上)
*
* */
let appState = {
title:{
text:'Reactjs 小书',
color:'red'
},
content:{
text:'性能提高',
color: 'blue'
}
};
function createStore(state,stateChanger){
const listeners = [];
const getState = ()=> state;
const subscribe = (listener) => listeners.push(listener);
const dispatch = (action) => {
state = stateChanger(state,action); //覆盖原来的对象
listeners.forEach((listener) => listener());
};
return {dispatch,getState,subscribe}
}
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; //没有修改,返回原来的state对象
}
}
function renderApp(newAppState,oldAppState={}) {
if(newAppState === oldAppState) return;
console.log('renderApp');
renderTitle(newAppState.title,oldAppState.title);
renderContent(newAppState.content,oldAppState.content);
}
function renderTitle(newTitle,oldTitle={}) {
if(newTitle === oldTitle) return;
console.log('renderTitle');
const titleDOM = document.getElementById('title');
titleDOM.innerHTML = newTitle.text;
titleDOM.style.color = newTitle.color;
}
function renderContent(newContent,oldContent = {}) {
if(newContent === oldContent) return;
console.log('renderContent');
const contentDOM = document.getElementById('content');
contentDOM.innerHTML = newContent.text;
contentDOM.style.color = newContent.color;
}
const store = createStore(appState,stateChanger);
let oldState = store.getState();
renderApp(store.getState());
store.subscribe(() => {
const newState = store.getState();
console.log(newState);
console.log(oldState);
renderApp(newState,oldState);
oldState = newState;
});
store.dispatch({type:'UPDATE_TITLE_COLOR',color:'yellow'});
store.dispatch({type:'UPDATE_TITLE_COLOR',color:'yellow'});