跳转到内容

React

@iostore/react 基于 useSyncExternalStore 对齐 React 渲染模型,适合生产场景的稳定订阅。

  • React 函数组件状态订阅。
  • 需要细粒度更新控制与选择器优化。
  • 需要与派生值、行为扩展组合使用。

安装相关依赖(任选一种包管理工具):

Terminal window
npm i @iostore/store @iostore/react
import { io } from '@iostore/store';
import { useIO } from '@iostore/react';
const count = io(0);
export function Counter() {
const value = useIO(count);
return <button onClick={() => count.set((v) => v + 1)}>{value}</button>;
}
import { io } from '@iostore/store';
import { derived } from '@iostore/store/derived';
import { useIO } from '@iostore/react';
const store = io({ count: 0 });
const doubled = derived([store.count], (value) => value * 2);
export function Summary() {
const value = useIO(doubled);
return <span>{value}</span>;
}
import { io } from '@iostore/store';
import { useIOSelector } from '@iostore/react';
const store = io({ count: 0, other: 0 });
export function CountOnly() {
const count = useIOSelector(store, (state) => state.count);
return <span>{count}</span>;
}

对象选择器建议提供 isEqual

const parity = useIOSelector(store, (state) => ({ p: state.count % 2 }), {
isEqual: (prev, next) => prev.p === next.p,
});
const value = useIO(count, { schedule: 'microtask' });

可选值:sync | microtask | animationFrame

场景API说明
读取 Unit/DeriveduseIO(unitOrDerived, options?)组件自动订阅并在变更时重渲染。
读取 Scope 片段useIOSelector(scope, selector, options?)用选择器裁剪订阅范围。
选择器比较options.isEqual(prev, next)避免对象选择器导致重复渲染。
通知调度options.schedulesync / microtask / animationFrame
批量写入batch(fn)高频交互建议配合使用。
// 错误:selector 每次返回新对象,且没有 isEqual
const view = useIOSelector(store, (s) => ({ count: s.count }));
// 推荐:补充 isEqual
const view2 = useIOSelector(store, (s) => ({ count: s.count }), {
isEqual: (a, b) => a.count === b.count,
});
// 错误:组件订阅根节点过大
const state = useIO(store);
// 推荐:只订阅路径 Unit
const count = useIO(store.count);
  • 选择器每次返回新对象且无比较函数,导致多余渲染。
  • 组件订阅根节点过大,影响渲染范围。
  • 高频写入不做 batch(),导致通知过密。
  • 优先路径订阅,其次 selector,最后根订阅。
  • selector 返回对象时优先配置 isEqual
  • Batching 组合减少中间态渲染。
  • 接入 DevTools 查看时间线与差异。
  • 结合 Persist 做本地持久化。
  • 需要 SSR 时,查看 Next.js 实战章节。