提高react渲染性能

155 阅读1分钟
/*
* @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'});