我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

大家都知道,redux无论哪一种写法,都是最终导出一个store对象,供外部调用。在上一篇的useSyncExternalStore适配redux的文章里面,大家可以看到:redux提供的store数据是可以提供给useSyncExternalStore进行订阅的。

苏南大叔:react教程,模拟store代码完美适配useSyncExternalStore - 模拟store适配useSyncExternalStore
react教程,模拟store代码完美适配useSyncExternalStore(图4-1)

苏南大叔的程序如此灵动博客,记录苏南大叔的代码感悟。测试环境:create-react-app@5.0.1node@16.14.2react@18.2.0react-dom@18.2.0

前文回顾

本文和下面这篇文章高度相关,可以先参考如下文章:
https://newsn.net/say/react-usesyncexternalstore-redux.html

上文中的主要内容就是:用过时的createstore()方法,定义一个reduxstore。然后在react里面使用useSyncExternalStore订阅上述store

主要代码如下:

const store = {......}
const Sunan = function () {
  const state = useSyncExternalStore(store.subscribe, () => store.getState().count)
  return (
    <div>
      {state}
      <button onClick={() => store.dispatch({ type: 'ADD' })} >苏南大叔加1</button>
    </div>
  )
}

苏南大叔:react教程,模拟store代码完美适配useSyncExternalStore - 关键代码usesyncexternalstore
react教程,模拟store代码完美适配useSyncExternalStore(图4-2)

自定义store

上一篇文章中,storeredux生成的,共有三个方法,分别是:

  • .subscribe(),订阅。
  • .getState(),返回数据。
  • .dispatch(),执行action

苏南大叔在网上看到了一段代码,很少的代码就实现了上述几个功能,完美兼容useSyncExternalStore系列代码。代码并不是苏南大叔原创的,版权归原作者所有。

const store = {
    state: { count: 0 },
    listeners: new Set(),
    reducer(action) {
        switch (action.type) {
            case 'ADD':
                return { count: store.state.count + 1 }
            default:
                return store.state
        }
    },
    subscribe(callback) {
        store.listeners.add(callback);
        return () => {
            store.listeners.delete(callback);
        }
    },
    getState() {
        return store.state
    },
    dispatch(action) {
        store.state = store.reducer(action)
        store.listeners.forEach(l => l())
        return action;
    }
}

苏南大叔:react教程,模拟store代码完美适配useSyncExternalStore - 自定义store
react教程,模拟store代码完美适配useSyncExternalStore(图4-3)

完整代码

完整代码如下:

import { useSyncExternalStore } from 'react';
function Sunan() {
    const count = useSyncExternalStore(store.subscribe, () => store.getState().count);
    return <div>
        <div>count:{count}</div>
        <div>
            <button onClick={() => store.dispatch({ type: 'ADD' })}>苏南大叔加一</button>
        </div>
    </div>
}
export default Sunan

const store = {
    state: { count: 0 },
    listeners: new Set(),
    reducer(action) {
        switch (action.type) {
            case 'ADD':
                return { count: store.state.count + 1 }
            default:
                return store.state
        }
    },
    subscribe(callback) {
        store.listeners.add(callback);
        return () => {
            store.listeners.delete(callback);
        }
    },
    getState() {
        return store.state
    },
    dispatch(action) {
        store.state = store.reducer(action)
        store.listeners.forEach(l => l())
        return action;
    }
}

从运行结果上来说,这段代码的运行效果和高大上的redux配合reactuseSyncExternalStore效果一致。

苏南大叔:react教程,模拟store代码完美适配useSyncExternalStore - 运行截图
react教程,模拟store代码完美适配useSyncExternalStore(图4-4)

相关文章

另外一个类式的自定义代码的文章,请参考:

结束语

更多react经验文章,请点击苏南大叔的博客文章:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   react