当前位置: 首页 > java >正文

基于 React Hook 封装 Store 的三种方案

基于 React Hook 封装 Store 的三种方案

方案一:基于 useSyncExternalStore 的轻量级 Store(推荐)
import { useSyncExternalStore } from 'react';type Store<T> = {state: T;listeners: Set<() => void>;
};function createStore<T>(initialState: T) {const store: Store<T> = {state: initialState,listeners: new Set(),};const setState = (updater: (prev: T) => T) => {store.state = updater(store.state);store.listeners.forEach(listener => listener());};const subscribe = (listener: () => void) => {store.listeners.add(listener);return () => store.listeners.delete(listener);};const useStore = <S>(selector: (state: T) => S): S => {return useSyncExternalStore(subscribe,() => selector(store.state),() => selector(initialState));};return [useStore, setState] as const;
}

特性:零依赖、无 Provider、精准渲染

方案二:基于 Context + useReducer
import { createContext, useContext, useReducer } from 'react';type State = { count: number };
type Action = { type: 'INCREMENT' } | { type: 'DECREMENT' };const StoreContext = createContext<{state: State;dispatch: React.Dispatch<Action>;
}>(null!);function StoreProvider({ children }) {const [state, dispatch] = useReducer((prev: State, action: Action) => {switch (action.type) {case 'INCREMENT': return { ...prev, count: prev.count + 1 };case 'DECREMENT': return { ...prev, count: prev.count - 1 };default: return prev;}},{ count: 0 });return (<StoreContext.Provider value={{ state, dispatch }}>{children}</StoreContext.Provider>);
}function useStore() {const { state, dispatch } = useContext(StoreContext);return {count: state.count,increment: () => dispatch({ type: 'INCREMENT' }),decrement: () => dispatch({ type: 'DECREMENT' })};
}

优势:支持中间件、复杂状态管理

方案三:基于闭包的轻量实现
import { useState, useMemo } from 'react';function createStore<T>(initialState: T) {let state = initialState;const listeners = new Set<() => void>();const setState = (updater: (prev: T) => T) => {state = updater(state);listeners.forEach(listener => listener());};function useStore(): [T, typeof setState] {const [, forceUpdate] = useState({});useMemo(() => {listeners.add(forceUpdate);return () => { listeners.delete(forceUpdate); };}, []);return [state, setState];}return useStore;
}

特点:<20行代码实现

方案选型对比
方案适用场景优点缺点
useSyncExternalStore大型应用全局状态高性能、无 Provider 污染需要 React 18+
Context + Reducer复杂业务流支持中间件、类型安全需要 Provider 包裹
闭包实现小型应用/组件间共享实现简单、零依赖无法跨组件树隔离状态
http://www.xdnf.cn/news/6609.html

相关文章:

  • 嵌入式故障码管理系统设计实现
  • 问题 | 国内外软件定义卫星最新进展研究
  • MySQL 高可用
  • DevExpressWinForms-RichEditControl-基础应用
  • 若依框架SpringBoot从Mysql替换集成人大金仓(KingBase)数据库
  • 【linux unbind 设备驱动】
  • API 加速方案:如何使用 Redis 与 Memcached 进行高效缓存优化
  • SpringBoot常用注解详解
  • 【蓝桥杯省赛真题50】python字母比较 第十五届蓝桥杯青少组Python编程省赛真题解析
  • ubuntu22鼠键失灵恢复记录笔记chatgpt解决
  • JavaScript性能优化实战(10):前端框架性能优化深度解析
  • nosqlbooster pojie NoSQLBooster for MongoDB
  • Android studio 实现弹出表单编辑界面
  • Cadence sch 删除原理图位号下划线
  • neo4j框架:ubuntu系统中neo4j安装与使用教程
  • c++20引入的三路比较操作符<=>
  • Linux-进程概念(一)
  • WAS和Tomcat的对比
  • 如何查询Ubuntu系统中最大的几个目录以G单位显示大小,从大到小排列?
  • 我用 CodeBuddy 开发了一个颜色命名搜索器 —— ColorNameHub 的诞生记
  • 在 Kotlin 中,什么是解构,如何使用?
  • 探索嵌入式硬件的世界:技术、应用与未来趋势
  • 知识蒸馏实战:用PyTorch和预训练模型提升小模型性能
  • LeetCode 746 使用最小花费爬楼梯
  • java -jar命令运行 jar包时如何运行外部依赖jar包
  • IEEE 列表会议第五届机器人、自动化与智能控制国际会议
  • python怎么将函数设置为保护状态
  • Suna: 开源多面手 AI 代理
  • MySQL数据库——支持远程IP访问的设置方法总结
  • LLM学习笔记(六)线性代数