Redux:动手实现

一、动手实现

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./js/jquery-3.2.1.min.js"></script>
</head>
<body>
    <div id='title'></div>
    <div id='content'></div>
<script>
    function renderApp(newAppState, oldAppState={}) { // 防止 oldAppState 没有传入,所以加了默认参数 oldAppState = {}
        if(newAppState == oldAppState) return;    // 数据没有变化就不渲染了
        console.log('render app...')
        renderTitle(newAppState.title, oldAppState.title);
        renderContent(newAppState.content, oldAppState.content);
    }
    function renderTitle(newTitle, oldTitle = {}) {
        if (newTitle === oldTitle) return;
        console.log('render title...');
        const titleDOM = document.getElementById('title');
        titleDOM.innerHTML = newTitle.text;
        titleDOM.style.color = newTitle.color;
    }
    function renderContent(newContent, oldContent = {}) {
        if (newContent === oldContent) return;
        console.log('render content...');
        const contentDOM = document.getElementById('content');
        contentDOM.innerHTML = newContent.text;
        contentDOM.style.color = newContent.color;
    }
</script>
<script src="./js/index.js"></script>
</body>
</html>

./js/index.js

//################################ 模拟实现redux核心函数 ################################

//reducer作用:初始化和计算新的 state
//       参数:state(数据)、action(如何修改数据)
function createStore(reducer) {
    let state = null;
    const listeners = [];
    const subscribe = (listener) => listeners.push(listener);
    const getState = () => state;
    const dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach((listener) => listener());
    };
    dispatch({});  // 初始化 state
    return {getState, dispatch, subscribe};
}


//################################ 使用方式 ################################

//··········· (1) 定一个 reducer
//stateChanger既充当了获取初始化数据的功能,也充当了生成更新数据的功能
function stateChanger(state, action) {
    if(!state) {
        return {
            title: {
                text: 'React.js',
                color: 'red',
            },
            content: {
                text: 'React.js 内容',
                color: 'blue'
            }
        }
    }
    switch(action.type) {
        case 'UPDATE_TITLE_TEXT':
            return {
                ...state,
                title: {
                    ...state.title,
                    text: action.text
                }
            };
        case 'UPDATE_TITLE_COLOR':
            return {
                ...state,
                title: {
                    ...state.title,
                    color: action.color
                }
            };
        default:
            return state;
    }
}

//··········· (2) 生成 store
const store = createStore(stateChanger);
let oldState = store.getState() // 缓存旧的 state

//··········· (3) 监听数据变化重新渲染页面
store.subscribe(() => {
    const newState = store.getState();
    renderApp(newState, oldState);
    oldState = newState;
});

//··········· (4) 首次渲染页面
renderApp(store.getState());   

//··········· (5) 后面可以随意 dispatch 了,页面自动更新
store.dispatch({ type: 'UPDATE_TITLE_TEXT', text: '《hello React.js》' });
store.dispatch({ type: 'UPDATE_TITLE_COLOR', color: 'blue'});

输出:
在这里插入图片描述


二、讲解

1、核心函数createStore

(1)reducer

  • 作用:初始化和计算新的 state
  • 参数:state(数据)、action(如何修改数据)

(2)subscribe:

  • 作用:监听数据,变化重新渲染页面
  • 参数:一个函数

(3)dispatch:改变数据的唯一途径,每使用一次dispatch,都会自动自行一遍所有的subscribe,所以页面会自动更新

2、使用核心函数
//······················· (1)定一个 reducer    ·······················
function reducer (state, action) {
  /* 初始化 state 和 switch case */
}


//······················· (2)传给核心函数,生成 store    ·······················
const store = createStore(reducer)


// ·······················(3)监听数据变化重新渲染页面   ·······················
store.subscribe(() => renderApp(store.getState()))


//······················· (4)首次渲染页面   ·······················
renderApp(store.getState()) 


// ·······················(5)后面可以随意 dispatch 了,页面自动更新   ·····················
store.dispatch(...)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值