手动实现redux

前言

我们在学习react时候,最难啃下来的一块就是redux了。可能现在也有很多伙伴都是停留在只会用的阶段~
在这里插入图片描述
我们应该去深入了解一下redux是如何实现的,从而达到灵活运用。

今天,我们就手动实现一个简单的redux。
在实现redux之前,我们需要知道一下几点。

  • redux和react没有关系,redux可以用于任何框架中
  • connect不属于redux,而属于react-redux
  • redux是一个状态管理器。
  • 先忘记相关名词 reducer,store,dispatch,middleware等等

实现redux

实现一个简单的状态管理器

redux是一个状态管理器,那什么是状态呢?状态就是数据,比如计数器中count

let state = {
    count: 1
}
console.log(state)
state.count = 2;

现在已经完成来状态的访问和使用了。
当时这里有一个很明显的问题:修改count之后,使用了count的地方不能收到通知。我们可以使用发布-订阅模式来解决这个问题。

let state = {
    count: 1
}
state.count = 2;
let listeners = [];

// 订阅
function subscribe(listener) {
    listeners.push(listener);
}

function changeCount(count) {
    state.count = count;
    // 当count改变的时候,我们要去通知所有的订阅者
    for (let i = 0; i < listeners.length; i++) {
        const listener = listeners[i];
        listener();
    }
}

subscribe(()=> {
    console.log(state.count)
})

changeCount(5)

现在我们可以看到,我们修改count的时候,会输出相应的count值
现在有两个新的问题摆在我们面前。 这个状态管理器只能管理count,不够通用。 公共的代码要封装起来。

将公用代码封装起来

function createStore(initState) {
    let state = initState;
    let listeners = [];

    // 订阅
    function subscribe(listener) {
        listeners.push(listener)
    }

    function changeState(newState) {
        state = newState;
        // 通知
        for (let i = 0; i < listeners.length; i++) {
            const listener = listeners[i];
            listener()
        }
    }

    function getState() {
        return state;
    }

    return {
        subscribe,
        changeState,
        getState,
    }
}

// 我们来使用这个状态管理器管理多个状态, counter 和 info 试试
let initState = {
    counter: {
        count: 0,
    },
    info: {
        name: '',
        description: ''
    }
}

let store = createStore(initState)

store.subscribe(() => {
    let state = store.getState();
    console.log(`${state.info.name}: ${state.info.description}`)
});

store.subscribe(() => {
    let state = store.getState()
    console.log(state.counter.count)
})

store.changeState({
    ...store.getState(),
    info: {
        name: '前端',
        description: '我们都是前端的爱好者!',
    }
})

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

实现一个有计划的状态管理器

与上一个代码块公用createStore函数

// 我们使用上面的状态管理器来实现一个自增,自减的计算器
let initState = {
    count: 0
}

let store = createStore(initState)

store.subscribe(() => {
    let state = store.getState()
    console.log(state.count)
})

store.changeState({
    count: store.getState().count + 1
})

store.changeState({
    count: store.getState().count - 1
})

store.changeState({
    count: 'abc',
})

这里有个问题,count被改成了字符串abc,因为我们对count的修改没有任何约束,任何地方,任何人都能修改。
我们需要约束,不允许计划外的count修改。我们只允许count自增和自减两种改变方式。
我们分两部来解决这个问题
1、指定一个state修改计划,告诉store,我们的修改计划是什么
2、修改store.changeState方法,告诉它修改state的时候,按照我们的计划修改.

对createStore函数进行修改

function createStore(plan, initState) {
    let state = initState;
    let listeners = [];

    // 订阅
    function subscribe(listener) {
        listeners.push(listener)
    }

    function changeState(action) {
        state = plan(state, action);
        // 通知
        for (let i = 0; i < listeners.length; i++) {
            const listener = listeners[i];
            listener()
        }
    }

    function getState() {
        return state;
    }

    return {
        subscribe,
        changeState,
        getState,
    }
}

let initState = {
    count: 0,
}

function plan(state, action) {
    switch(action.type) {
        case 'INCREMENT':
            return {
                ...state,
                count: state.count + 1
            }
        case 'DECREMENT':
            return {
                ...state,
                count: state.count - 1
            }
        default: 
            return state
    }
}

let store = createStore(plan, initState)

store.subscribe(() => {
    let state = store.getState()
    console.log(state)
})

store.changeState({
    type: 'INCREMENT'
})

store.changeState({
    type: 'DECREMENT'
})

store.changeState({
    count: 'abc'
})

到这里,我们就实现了一个最基本的redux了。
其中,plan就是reduer,changeState就是dispatch。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值