Appearance
传参响应式问题:主流处理方式 & 最佳实践
本节目标:理解“传参响应式问题:主流处理方式 & 最佳实践”的核心思路,并能把它用于实际开发或面试表达。 主流处理方式 & 最佳实践
| 场景 | 做法 | 说明 |
| 字段本身会变(💰 动态数据、开关、阈值…) | 把字段包成 Signal/Ref/Getter,再传给 useDataItem | 示例:decimals: () => myStore.decimals 或 decimals: decimalsSignal |
| 字段只在少数场景整体换一批 | 直接重新调用 useDataItem 或 setOptions | React/TanStack 的做法:table.setOptions(prev => ({ ...prev, decimals })) |
| 想用一个对象统一改动多个字段 | 让整个 options 本身是 Signal/Ref,内部再分解 | const optionsSig = Signal.state(initOptions); useDataItem(optionsSig); optionsSig.set({ ...old, decimals: 4 }) |
一句话:要变就给“响应式包装”,要不变就传字面量; 如果你改的是字面量字段,就必须 换引用,否则没人知道它变了。
具体改动:让所有可变字段支持 MaybeRefOrGetter
- types.ts
ts 复制编辑 export interface DataItemOptions { label: string; separator?: MaybeRefOrGetter<string>; /* 动态值 / value: MaybeRefOrGetter<number>; loading?: MaybeRefOrGetter<boolean>; / 可能在运行期切换的展示配置也给成 MaybeRefOrGetter */ decimals?: MaybeRefOrGetter<number>; extraDigits?: MaybeRefOrGetter<number>; prefix?: MaybeRefOrGetter<string>; suffix?: MaybeRefOrGetter<string>; unit?: MaybeRefOrGetter<string>; formatter?: (v: number) => string; thresholds?: MaybeRefOrGetter<Thresholds>;}
- useDataItem.ts****保持你现有逻辑,只确认用 resolve() 解包即可(你已经这么做了)
示例:三种更新方式① 字段自己是 Signal(最推荐)
ts 复制编辑 // 假设 decimals 会随用户设置变化const decimalsSig = Signal.state(2) // 调用const item = useDataItem({ label: '价格', value: priceSig, // Signal decimals: decimalsSig, // Signal prefix: '$',}) // 修改decimalsSig.set(4) // useDataItem 内部会自动响应 ② 整个 options 是 Signal
ts 复制编辑 const opts = Signal.state({ label: '价格', value: priceSig, decimals: 2, prefix: '$',}) const item = useDataItem(opts) // 批量修改时换引用opts.set({ ...opts.get(), decimals: 4, prefix: 'USD ' }) ③ 像 TanStack-React 那样:显式 setOptions
tsx 复制编辑 // React 伪码const [item, setItemOptions] = useState(initOptions) useEffect(() => { setItemOptions(prev => ({ ...prev, decimals }))}, [decimals])
TanStack Table 的做法
- 核心库:只在外层调用 table.setOptions() 时重新读取;不监听深层字段。
- React 适配层:每次组件渲染都会最少调用一次 instance.setOptions(...),并把依赖写进 useMemo() 里,依赖变 ⇒ 新引用 ⇒ Table 重算。
- Solid / Vue 适配层:用 createMemo / watchEffect 包住 setOptions,依靠框架 reactivity 感知字段变化。
同一个模式:要么字段自己是 reactive,要么外层换引用并显式 setOptions。
结论
- 你想变的字段 ➜ 包成 Signal / Ref / Getter 传进去;
- 你不想管的静态配置 ➜ 直接字面量;
- 如果要一次改动多项 ➜ 要么把整个 options 包成 Signal,要么重新执行 useDataItem / setOptions。
遵循这套思路,你的组件就能和 TanStack 一样既保持“核心纯 JS”又能轻松接入各种响应式框架。
