封裝redux中的createStore

大灰狼的小綿羊哥哥發表於2019-11-14

redux用於react中的狀態管理,其中不能直接修改redux中的狀態,需要通過dispatch方法才能修改react中的狀態。

createStore函式中存放著狀態資訊state,它的執行結果返回一個store物件,返回的物件包含:

getState(獲取store中的state狀態資訊,但是不能直接修改store中的state資訊)
dispatch(修改store中的state資訊)
subscribe(用於訂閱事件)
<div>
    <div id="title"></div>
    <div id="content"></div>
</div>
<script>
    function createStore(reducer) {
        // 定義store物件中的狀態資訊物件,此處必須是隻定義不賦值,因為這樣在下面的dispatch初始化state時才能使用預設值初始化state
        let state;
        // listener是一個事件池,儲存訂閱的方法
        let listener = [];
        // 在createStore作用域下建立getState函式,該函式需要返回一個新物件,該物件需要和state一樣。這個方法只用於獲取state
        // 深克隆:將當前作用域下的state深克隆一份,讓外界利用這個方法只能獲取state不能修改state
        let getState = () => JSON.parse(JSON.stringify(state));
        // 定義修改state的函式dispatch。action中的type一般是const大寫的常量
        function dispatch(action) {
            state = reducer(state,action);
            // 在dispatch中執行訂閱的方法
            listener.forEach((item,index)=>{
                if(typeof item==="function"){
                    item();
                }
            });
        }
        // 這個函式的執行是在初始化state物件
        dispatch({});
        // 在createStore中有一個訂閱方法subscribe,該函式返回取消訂閱的函式
        let subscribe = (fn)=>{
            listener.push(fn);
            // 返回取消訂閱的方法,當返回值執行時就會取消該訂閱
            return ()=>{
                listener = listener.filter(item=>item!==fn);
            };
        };
        return {
            getState, dispatch,subscribe
        };
    }
    let initState = {
        title: { color: 'red', text: '你好' },
        content: { color: 'yellow', text: '中國' }
    };
    const CHANGE_TITLE_TEXT = "CHANGE_TITLE_TEXT";
    const CHANGE_CONTENT_COLOR = "CHANGE_CONTENT_COLOR";
    function reducer(state = initState, action) {
        switch (action.type) {
            case CHANGE_TITLE_TEXT:
                // 當解構出現重名,後面覆蓋前面
                return { ...state, title: { ...state.title, text: action.text } };
            case CHANGE_CONTENT_COLOR:
                return { ...state, content: { ...state.content, color: action.color } };
            default:
                return state;
        }
    }
    let store = createStore(reducer);
    // 資料渲染title、content
    function renderTile() {
        let title = document.getElementById("title");
        title.innerHTML = store.getState().title.text;
        title.style.color = store.getState().title.color;
    }
    function renderContent() {
        let content = document.getElementById("content");
        content.innerHTML = store.getState().content.text;
        content.style.color = store.getState().content.color;
    }
    function renderApp() {
        renderTile();
        renderContent();
    }
    renderApp();
    // redux中規定,不能直接修改state中的資料,必須通過dispatch來修改state中的資料
    let f = store.subscribe(renderApp);
    // f();//這個方法執行就會取消訂閱的方法
    setTimeout(() => {
        store.dispatch({ type: CHANGE_TITLE_TEXT, text: '加油' });
        store.dispatch({ type: CHANGE_CONTENT_COLOR, color: 'black' });
        // renderApp();
    }, 3000);
</script>

————————————————
版權宣告:本文為CSDN博主「fengyezi159」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/u010510187/article/details/101557187

相關文章