简介

实现一个简单的Redux,以便更好地理解Redux

state

coust state = {
    count:1
}
state.count = 2
console.log(state.count)//2

这样就可以直接改变state里面的值,但是改变state里面的值后没有人知道呀,所以引入发布订阅模式

subcribe

const listeners = []
function subscribe(listener){
    listeners.push(listener)
}
subcribe(()=>{
    state.count = count
})
function setCount(count){
    state.count = count
    listeners.forEach(item=>item())
}
setCount(2)//2
setCount(3)//3

这样就知道改变数据了

代码封装

function createStore(initState) {
    let state = initState
    let listeners = []
    //订阅
    function subscribe(listener) {
        listeners.push(listener)
    }
    function changeState(newState) {
        listeners.forEach(item=>item())
        state = newState
    }
    function getState() {
        return state
    }
    return {
        subscribe,
        changeState,
        getState
    }
}

接下来创建一个store

let store = createStore(initState)
store.subscribe(() => {
    let state = store.getState();
    console.log(`${state.user.name}:${state.user.age}`);
});
store.subscribe(() => {
    let state = store.getState();
    console.log(state.counter.count);
});

store.changeState({
    ...store.getState(),
    user: {
        name: 'qweqweqwe',
        age: '1212'
    }
});

store.changeState({
    ...store.getState(),
    counter: {
        count: 12222
    }
});

reducer和action

改造如下

function createStore(initState, reducer) {
    let state = initState
    let listeners = []
    //订阅
    function subscribe(listener) {
        listeners.push(listener)
    }

    function dispatch(action) {
        listeners.forEach(item => item())
        state = reducer(state, action)
    }

    function getState() {
        return state
    }
    return {
        subscribe,
        dispatch,
        getState
    }
}
let initState = {
    count: 0
}

function reducer(state, action) {
    switch (action.type) {
        case 'INCREMENT':
            return {
                ...state,
                count: state.count + 1
            }
            break;
        case 'DECREMENT':
            return {
                ...state,
                count: state.count - 1
            }
            break;
        default:
            break;
    }
}
let store = createStore(initState, reducer)
store.dispatch({
    type: 'INCREMENT'
})
store.dispatch({
    type: 'INCREMENT'
})
store.dispatch({
    type: 'DECREMENT'
})

中间件

中间件是对dispatch的一个加强,下面是一个例子

记录日志中间件

//重写了dispatch方法,先用next缓存之前的dispatch方法
let store = createStore(initState, reducer)
let next = store.dispatch
store.dispatch = action => {
    console.log(`action:${action}`)
    console.log(`state:${store.getState()}`)
    next(action)
    console.log(`next state : ${store.getState()}`)
}

记录异常

let store = createStore(initState, reducer)
let next = store.dispatch
store.dispatch = action => {
    try{
        next(action)
    }catch(e){
        throw new Error(e)
    }
}

多中间件合作

function createStore(initState, reducer) {
    let state = initState
    let listeners = []
    //订阅
    function subscribe(listener) {
        listeners.push(listener)
    }

    function dispatch(action) {
        listeners.forEach(item => item())
        state = reducer(state, action)
    }

    function getState() {
        return state
    }
    return {
        subscribe,
        dispatch,
        getState
    }
}
let initState = {
    count: 0
}

function reducer(state, action) {
    switch (action.type) {
        case 'INCREMENT':
            return {
                ...state,
                count: state.count + 1
            }
            break;
        case 'DECREMENT':
            return {
                ...state,
                count: state.count - 1
            }
            break;
        default:
            break;
    }
}
let store = createStore(initState, reducer)
let next = store.dispatch
const loggerMiddleware = function (next) {
    return function (action) {
        console.log('this state', store.getState());
        console.log('action', action);
        next(action);
        console.log('next state', store.getState());
    }
}
const exceptionMiddleware = function (next) {
    return function (action) {
        try {
            next(action);
        } catch (err) {
            console.error('错误报告: ', err)
        }
    }
}
store.dispatch = exceptionMiddleware(loggerMiddleware(next))
store.dispatch({
    type: 'INCREMENT'
})
console.log(store.getState())

不太理解的可以在浏览器debugger一遍,过程就很清晰了
图片说明