Appearance
React 状态管理解决方案
安装
sh
pnpm install @yl_lowcode/reactivesh
npm install @yl_lowcode/reactivereactive 响应式状态管理
基于 useSyncExternalStore 封装的轻量响应式状态管理方案,无需 Context,天然支持 SSR,具备自动依赖追踪与深层嵌套响应能力。
基础用法
调用 reactive(initialState) 创建一个 store,在组件内通过 store.useSnapshot() 订阅状态,像操作普通对象一样直接赋值即可触发更新。
ts
import reactive from "@yl_lowcode/reactive";
const store = reactive({ count: 0 });
// 读
console.log(store.count);
// 写(自动触发订阅组件重渲染)
store.count++;
store.count = 10;跨组件共享
store 在模块作用域创建,天然实现跨组件状态共享——任意一处修改,所有订阅组件同步更新,无需 props 透传或 Context。
自动依赖追踪
useSnapshot() 返回的快照具备自动依赖追踪能力:解构了哪些 key 就只监听哪些 key,其余字段变化不触发当前组件重渲染。
tsx
// ✅ 只依赖 count,name 变化时此组件不重渲染
function CountPanel() {
const { count } = store.useSnapshot();
return <div>{count}</div>;
}
// ✅ 只依赖 name,count 变化时此组件不重渲染
function NamePanel() {
const { name } = store.useSnapshot();
return <div>{name}</div>;
}注意:若直接使用整个快照对象(
const snap = store.useSnapshot())而不解构,等价于订阅所有字段,任意字段变化都会触发重渲染。
嵌套对象深层响应
对嵌套对象属性直接赋值,无需手动触发更新,任意层级的修改都会自动冒泡到根 store 并通知订阅组件。
ts
const store = reactive({
user: {
name: "Alice",
address: { city: "上海" },
},
});
// ✅ 任意层级直接赋值,自动触发更新
store.user.name = "Bob";
store.user.address.city = "北京";限制:深层响应仅对普通对象生效,
Array、Map、Set等容器类型的方法(如push、set)不会自动触发更新,需替换整个引用:ts// ❌ push 不触发更新 store.list.push(1); // ✅ 替换引用触发更新 store.list = [...store.list, 1];
重置初始状态
调用 store.restore() 将 store 的所有字段重置为初始值并触发视图更新。当所有订阅该 store 的组件全部卸载时,store 也会自动还原到初始状态,下次挂载时始终是干净的初始数据。
ts
// 手动重置
store.restore();最佳实践
Store 定义建议放在模块顶层
ts
// store.ts
import reactive from "@yl_lowcode/reactive";
export const userStore = reactive({
name: "",
age: 0,
role: "viewer" as "viewer" | "editor" | "admin",
});按功能拆分多个 store
ts
// 避免一个巨大的全局 store,按功能域拆分
export const authStore = reactive({ token: "", userId: "" });
export const themeStore = reactive({ mode: "light", accent: "#6366f1" });
export const cartStore = reactive({ items: [] as CartItem[], total: 0 });在事件处理函数中批量修改
ts
// 多次赋值会触发多次 dispatch,如需批量更新,建议直接替换对象
store.user = { ...store.user, name: "Bob", age: 25 };API
reactive(initialState)
创建并返回一个响应式 store。
| 参数 | 类型 | 说明 |
|---|---|---|
initialState | T | store 的初始状态对象 |
返回值 T & { useSnapshot, restore }
store.useSnapshot()
React Hook,在组件中订阅 store,返回当前快照(浅冻结)。
- 自动追踪本次渲染中访问过的 key,仅当这些 key 对应的值变化时才触发重渲染
- 返回值顶层属性被
Object.freeze保护,严格模式下直接修改会抛出运行时异常 - 必须在 React 函数组件或自定义 Hook 内调用(遵循 React Hooks 规则)
ts
const { count, name } = store.useSnapshot();store.restore()
将 store 重置为 reactive() 调用时传入的初始状态,并触发视图更新。
ts
store.restore();内部保留属性
以下属性名为 store 内部保留,不可作为 state 的 key 使用:
| 属性名 | 说明 |
|---|---|
state | 原始 state 对象 |
originStore | 初始状态快照(供 restore 用) |
listeners | 订阅者集合 |
subscribe | 订阅方法 |
getSnapshot | 快照读取方法 |
dispatch | 内部触发更新方法 |
useSnapshot | React Hook |
restore | 重置方法 |
TypeScript 会在编译期对使用保留名的 state key 进行报错提示。