React手写一个正式版本的redux

import React from 'react'
//播放器

const renderScreen = (newScreen, oldScreen = {}) => {
    if (newScreen === oldScreen) 
        return;
    console.log("=============>renderScreen");
    //获取页面元素 
    const sc = document.querySelector('#screen');
    //对页面元素进行修改 
    sc.innerHTML = `${newScreen.title}:${store.getState().isPlaying}`;
};

const renderButton = (newButton, oldButton = {}) => {
    if (newButton === oldButton) 
        return;
    console.log("=============>renderButton");
    //获取页面元素 
    const btn = document.querySelector('#button');
    //对页面元素进行修改 
    btn.innerHTML = newButton.text;
};

//1.全局渲染方法
const renderApp = (newState, oldState = {}) => {
    if (newState === oldState) {
        return;
    }
    console.log("renderApp state-->", newState);
    //渲染屏幕 
    renderScreen(newState.screen, oldState.screen);
    //渲染按钮 
    renderButton(newState.button, oldState.button);
};

//2.对状态的修改交给纯函数去做
// 定义修改数据方法
const reducer = (state, action) => {
    //首先对操作类型进行判断 
    switch (action.type) {
        case 'play_video':
            return {
                isPlaying: true, 
                button: {
                    text: '停止'
                },
                screen: {
                    title: action.title
                }
            };
        case 'stop_video':
            return {
                isPlaying: false, 
                button: {
                    text: '播放'
                },
                screen: {
                    title: action.title
                }
            };
        case 'play_next':
            return {
                ...state, 
                screen: {
                    title: action.title
                }
            };
        default:
            return state;
    }
};

//3.所以我们定义一个createStore来管理全局状态
// 直接暴露数据不安全,会带来不可预知的错误
const createStore = (reducer) => {
    //局部作用域 
    // 初始化数据 
    let state = {
        isPlaying: false,
        screen: {
            title: 'java is easy'
        },
        button: {
            text: '播放'
        }
    };
    //声明监听数组 
    let listeners = [];
    //获取数据方法 
    const getState = () => state;
    //来修改数据 
    const dispatch = (action) => {
        //1)修改状态 
        state = reducer(state, action);
        //2)调用所有监听 
        listeners.forEach(listener => listener());
    };
    //提供一个订阅方法 
    const subscribe = (listener) => {
        listeners.push(listener)
    };
    //暴露方法 
    return {getState, dispatch, subscribe};
};

//4.使用createStore函数来创建数据逇管理对象
const store = createStore(reducer);

//声明一个老状态
let oldState = store.getState();

//当状态发生修改时候
store.subscribe(() => {
    //获取最新状态 
    const newState = store.getState();
    //重新渲染 
    renderApp(newState, oldState);
    //更新老状态 
    oldState = newState;
});

//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: '下班了再见'});
    }
});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花生糖葫芦侠

创作不易,请多多支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值