React手写一个正式版本的redux

本文介绍了一个基于React的简易播放器应用实现方案,利用纯函数和状态管理来控制播放器的状态变化,包括播放、暂停及下一曲等功能。通过定义全局状态、监听状态变化并触发UI更新,展示了如何有效地组织代码和保持组件的纯净。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

花生糖葫芦侠

创作不易,请多多支持!

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

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

打赏作者

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

抵扣说明:

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

余额充值