1. 程式人生 > >Redux自己手寫一個簡化版全面的redux

Redux自己手寫一個簡化版全面的redux

import React from 'react'

//播放器

const renderScreen = (screen)=>{
    console.log("=============>renderScreen");
    //獲取頁面元素
    const sc = document.querySelector('#screen');
    //對頁面元素進行修改
    sc.innerHTML = `${screen.title}:${store.getState().isPlaying}`;
};

const renderButton = (button)=>{
    console.log("=============>renderButton");
    //獲取頁面元素
    const btn = document.querySelector('#button');
    //對頁面元素進行修改
    btn.innerHTML = button.text;
};

//1.全域性渲染方法
const renderApp = (state)=>{
    console.log("renderApp state-->",state);
    //渲染螢幕
    renderScreen(state.screen);
    //渲染按鈕
    renderButton(state.button);
};

//2.對狀態的修改交給純函式去做
//定義修改資料方法
const changeStateFn = (state,action)=>{
    //首先對操作型別進行判斷
    switch (action.type){
        case 'play_video':
            //修改播放狀態
            state.isPlaying = true;
            //修改按鈕
            state.button = {
                text:'停止'
            };
            state.screen.title = action.title;
            console.log(action,state);
            break;
        case 'stop_video':
            //修改播放狀態
            state.isPlaying = false;
            //修改按鈕
            state.button = {
                text:'播放'
            };
            state.screen.title = action.title;
            console.log(action,state);
            break;
        case 'play_next':
            state.screen.title = action.title;
            break;
        default:
    }
};

//3.所以我們定義一個createStore來管理全域性狀態
//直接暴露資料不安全,會帶來不可預知的錯誤
const createStore = (changeStateFn)=>{
    //區域性作用域
    //初始化資料
    let state = {
        isPlaying:false,
        screen:{
            title:'java is easy'
        },
        button:{
            text:'播放'
        }
    };
    //宣告監聽陣列
    let listeners = [];
    //獲取資料方法
    const getState = ()=>state;
    //來修改資料
    const dispatch = (action)=> {
        //1)修改狀態
        changeStateFn(state,action);
        //2)呼叫所有監聽
        listeners.forEach(listener=>listener());
    };
    //提供一個訂閱方法
    const subscribe = (listener)=>{
        listeners.push(listener)
    };
    //暴露方法
    return {getState,dispatch,subscribe};
};

//4.使用createStore函式來建立資料逇管理物件
const store = createStore(changeStateFn);

//當狀態發生修改時候
store.subscribe(()=>{
    //重新渲染
    renderApp(store.getState());
});

//5.全域性初始化
renderApp(store.getState());

//6.對按鈕進行監聽
document.querySelector("#button").addEventListener('click',()=>{
    //判斷播放狀態
    if(!store.getState().isPlaying){
        store.dispatch({type:'play_video',title:'發現不斷,精彩不停...'});
        setTimeout(()=>{
            store.dispatch({type:'play_next',title:'每一次相遇都不是偶然'});
        },2000);
    }else {
        store.dispatch({type:'stop_video',title:'下班了再見'});
    }
});