【Redux】手撸一套redux和react-redux,深入学习(二)

手撸一套redux和react-redux,深入学习


回顾

https://blog.csdn.net/tuzi007a/article/details/129645629

Redux

上篇已经实现了状态的获取和更新,如何实现状态更新后通知用到该状态的组件去更新为最新状态呢?这里使用了最基础的观察者模式。我们先来简单看下观察者模式

// 观察者
class Observer {
	constructor(fn) {
		this.update = fn;
	}
}

// 被观察者
class Subject {
	constructor() {
		this.observers = [];
	}

	addObserver(observer) {
		this.observers.push(observer);
	}

	notify() {
		this.observers.forEach(observer => {
			observer.update();
		})
	}
}
const subject = new Subject();
const update1 = () => {console.log('boserver1 数据更新了')};
const update2 = () => {console.log('boserver2 数据更新了')};
const observer1 = new Observer(update1);
const observer2 = new Observer(update2);
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notify()

在这里插入图片描述

观察者在监听时,定义了一个回调函数,被观察者把观察者们加入观察者列表,在数据更新时, 执行notify通知观察者们,调用它们的回调函数update。总而言之,被观察者需要准备一个回调函数,想要监听数据时,就把自己的回调函数添加到观察者列表里。观察者准备一个观察者列表,在通知时,执行观察者的回调函数即可。如果想要取消监听,只需要把该观察者在观察者列表的回调函数删除即可。现在我们来实现一下

const createStore = (reducer) => {
    let currentState = {};
    // 存储观察者,我们用Map储存,方便在取消监听的时候进行删除操作
    const listeners = new Map();
    // 准备一个序列号,方便对观察者操作
    let listenerCount = 0;
    
    function getState() {
        return currentState;
    }

    function dispatch(action) {
        currentState = reducer(currentState, action);

        // 更新状态时,及时执行回调,通知观察者
        listeners.forEach(listener => listener());
    }

    function subscribe(listener) { 
        // 每添加一个监听者,序列号就自增1
        // listenerCount也是被闭包存储的变量
        // 所以它会一直增加,不用担心序列号重复的问题
        const listenerId = listenerCount++;
        listeners.set(listenerId, listener);

        // 返回一个取消监听的函数
        return function unsubscirbe () {
            listeners.delete(listenerId);
        }
    }

    dispatch({ type: '@@REDUX__INIT' });
    
    return { getState, dispatch, subscribe };
}

我们来测试一下

// src/index.js

console.log('store1: ', store.getState());

store.subscribe(() => {
    console.log('数据更新了:', store.getState());
})

store.dispatch({ type: 'increament' }); // 增加
store.dispatch({ type: 'increament' }); // 增加
store.dispatch({ type: 'decreament' }); // 减少

在这里插入图片描述

这样就实现了状态的监听,及时更新数据。另外,还需要验证一下取消监听是否有效,再写个例子

console.log('store1: ', store.getState());

const unsubscribe = store.subscribe(() => {
    console.log('数据更新了:', store.getState());
})

store.dispatch({ type: 'increament' }); // 增加
store.dispatch({ type: 'increament' }); // 增加
store.dispatch({ type: 'decreament' }); // 减少

unsubscribe(); // 取消监听

store.dispatch({ type: 'increament' }); // 增加
store.dispatch({ type: 'increament' }); // 增加

在这里插入图片描述
可以看到,在取消监听后的两次增加行为,并没有进行通知,取消监听是有效的。这样也验证了取消监听的功能。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值