<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## 第一版 ``` let appState = { title:{color:'red',text:'標題'} ,content:{color:'green',text:'內容'} }; // change(appState); function renderTitle(title){ // appState = null; let element = document.querySelector('#title'); element.innerHTML = title.text; element.style.color = title.color; } function renderContent(content){ let element = document.querySelector('#content'); element.innerHTML = content.text; element.style.color = content.color; } function renderApp(state){ renderTitle(state.title); renderContent(state.content); } renderApp(appState); ``` 問題: 此時狀態是一個全局變量,任何地方都可以改 例如第八行 就會造成毀滅性結果 ## 第二版 改進: 增加修改的門檻 ``` const UPDATE_TITLE_COLOR = 'UPDATE_TITLE_COLOR'; const UPDATE_TITLE_TEXT = 'UPDATE_TITLE_TEXT'; const UPDATE_CONTENT_COLOR = 'UPDATE_CONTENT_COLOR'; const UPDATE_CONTENT_TEXT = 'UPDATE_CONTENT_TEXT'; // 派發分發的意思 // action動作 動作 描述一下你想干什么,動作是一個普通的js對象,只有一個屬性是必須的 type屬性 其它屬性隨意 function dispatch(action){ //{type:UPDATE_TITLE_COLOR,color:'purple'} switch(action.type){ case UPDATE_TITLE_COLOR: appState.title.color = action.color; break; case UPDATE_TITLE_TEXT: appState.title.text = action.text; break; case UPDATE_CONTENT_COLOR: appState.content.color = action.color; break; case UPDATE_CONTENT_TEXT: appState.content.text = action.text; break; default: throw new Error('你發給我的指令我不認識或無法處理!'); } } setTimeout(function(){ dispatch({type:UPDATE_TITLE_COLOR,color:'orange'}); dispatch({type:UPDATE_CONTENT_TEXT,text:'新內容'}); renderApp(appState) },2000); ``` 問題: 此時我們仍然可以直接修改appState ## 第三版 改進: 定義一個方法,創建一個倉庫,這個倉庫其實一個對象,只不過可以引用閉包變量 ``` function createStore(){ let state = { title:{color:'red',text:'標題'} ,content:{color:'green',text:'內容'} }; function dispatch(action){ //{type:UPDATE_TITLE_COLOR,color:'purple'} switch(action.type){ case UPDATE_TITLE_COLOR: state.title.color = action.color; break; case UPDATE_TITLE_TEXT: state.title.text = action.text; break; case UPDATE_CONTENT_COLOR: state.content.color = action.color; break; case UPDATE_CONTENT_TEXT: state.content.text = action.text; break; default: throw new Error('你發給我的指令我不認識或無法處理!'); } } function getState(){ return JSON.parse(JSON.stringify(state)); //第二層保護 } return { getState,dispatch } } let store = createStore(); renderApp(store.getState()); setTimeout(function(){ store.dispatch({type:UPDATE_TITLE_COLOR,color:'orange'}); store.dispatch({type:UPDATE_CONTENT_TEXT,text:'新內容'}); renderApp(store.getState()); },2000); ``` 問題: 此時狀態和動作都是寫死的,createStore無法復用 ## 第四版 改進: 將dispatch做成了一個對外接口,讓用戶可以自定義動作 并將狀態的初始化綁定在了reducer上的第一個參數上 ``` function createStore(reducer){ let state; let listeners = []; function dispatch(action){ //{type:UPDATE_TITLE_COLOR,color:'purple'} state = reducer(state,action); //會返回一個新狀態 } function getState(){ return JSON.parse(JSON.stringify(state)); //第二層保護 } dispatch({}); //獲取初始狀態 return { getState,dispatch,subscribe } } let initState = { title:{color:'red',text:'標題'} ,content:{color:'green',text:'內容'} }; reduce處理的意思 處理器 根據老的狀態和拿到的動作 返回新的狀態 let reducer = function(state = initState,action){ switch(action.type){ case UPDATE_TITLE_COLOR: return {...state,title:{...state.title,color:action.color}}; //return 后自動break case UPDATE_TITLE_TEXT: return {...state,title:{...state.title,text:action.text}}; case UPDATE_CONTENT_COLOR: return {...state,content:{...state.content,color:action.color}}; case UPDATE_CONTENT_TEXT: return {...state,content:{...state.content,color:action.text}}; default: return state; //返回老狀態 } }; let store = createStore(reducer); renderApp(store.getState()); setTimeout(function(){ store.dispatch({type:UPDATE_TITLE_COLOR,color:'orange'}); store.dispatch({type:UPDATE_CONTENT_TEXT,text:'新內容'}); renderApp(store.getState()); },2000); ``` 問題: 仍然需要我們手動調用render刷新 ## 第五版 改進: 用發布訂閱來實現自動render刷新 ``` function createStore(reducer,preloadedState){ let state = preloadedState; let listeners = []; function dispatch(action){ //{type:UPDATE_TITLE_COLOR,color:'purple'} // 接收到新的動作后u通過老狀態 和新動作 計算出新狀態 state = reducer(state,action); //會返回一個新狀態 // 然后通知所有的監聽函數執行 listeners.forEach(cb => { console.log(1); cb(); }); } function getState(){ return JSON.parse(JSON.stringify(state)); //第二層保護 } dispatch({}); //獲取初始狀態 //在redux源碼中派發的是名為@@redux/init的東東 // 訂閱,供外界訂閱本倉庫中狀態的變化,如果狀態變化了會執行訂閱的邏輯 function subscribe(listener){ listeners.push(listener); //會返回一個取消訂閱函數 return function(){ listeners = listeners.filter(item=>item!=listener); } } return { getState,dispatch,subscribe } } let initState = { title:{color:'red',text:'標題'} ,content:{color:'green',text:'內容'} }; // reduce處理的意思 處理器 根據老的狀態和拿到的動作 返回新的狀態 let reducer = function(state = initState,action){ switch(action.type){ case UPDATE_TITLE_COLOR: return {...state,title:{...state.title,color:action.color}}; //return 后自動break case UPDATE_TITLE_TEXT: return {...state,title:{...state.title,text:action.text}}; case UPDATE_CONTENT_COLOR: return {...state,content:{...state.content,color:action.color}}; case UPDATE_CONTENT_TEXT: return {...state,content:{...state.content,text:action.text}}; default: return state; //返回老狀態 } }; let store = createStore(reducer); //可以傳入初始值 那么此時initStore將會失效 function render(){ renderTitle(store.getState().title); renderContent(store.getState().content); } render(); store.subscribe(render); let unsubscribe = store.subscribe(render); setTimeout(function(){ store.dispatch({type:UPDATE_TITLE_COLOR,color:'orange'}); unsubscribe(); store.dispatch({type:UPDATE_CONTENT_TEXT,text:'新內容'}); },2000); //為了方便action的書寫和避免寫錯,我們一般會寫一個函數來生成對應的action 方便檢查錯誤 有報錯 function updateTitleColor(color){ return {type:UPDATE_TITLE_COLOR,color} } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看