框架集成
将同一套 Coaction store 模型连接到 React、Vue、Angular、Svelte 或 Solid。
框架包使用各自生态原生的 reactive primitive 包装 core Store contract。状态创建、action、computed getter、slices 与共享模式规则仍由 core 提供。
React
@coaction/react 支持 React 18 与 19。CI 会分别安装这两个版本并跑完整测试,
所以这个范围是被验证过的,不是声明。
import { create, observer } from '@coaction/react';
const useCounter = create((set) => ({
count: 0,
increment() {
set(() => {
this.count += 1;
});
}
}));
const Counter = observer(() => {
const state = useCounter();
return <button onClick={state.increment}>{state.count}</button>;
});在 observer() 内,无 selector 的 hook 调用会追踪 render 期间读取的字段;在其外部则订阅整个 store。意图更清楚时可以显式选择:
const count = useCounter((state) => state.count);<Observer> 可创建更小的追踪区域,useCounter.auto() 返回缓存字段 selector map。
服务端渲染
服务端没有任何可订阅的东西,所以读取 store 的每一种方式都只是一次普通读取,读到的是那一刻的
状态 —— selector、不带 selector 的调用、observer 三者一致。
这在渲染之前已经有写入时才真正重要:请求预加载数据、hydration middleware、初始化的第二阶段。 三者都会报告被写入的那个值,而这也正是客户端 hydrate 时比对的值,所以 React 会接受这段 markup,而不是报告 mismatch 并重新渲染整棵树。
如果你要的是 store 创建时的值,就显式去取:
const initial = useCounter.getInitialState().count;Vue
import { create } from '@coaction/vue';
const useCounter = create((set) => ({
count: 0,
increment() {
set((draft) => {
draft.count += 1;
});
}
}));
export default {
setup() {
const state = useCounter();
const count = useCounter((current) => current.count);
return { state, count };
}
};useCounter({ autoSelector: true }) 为已知字段返回 computed ref。方法可直接调用,数据 ref 通过 .value 读取。
Angular
import { create } from '@coaction/ng';
const store = create(source);
const count = store.select((state) => state.count);
console.log(count());select() 为 selector 结果返回 Angular signal-like accessor。
Svelte
import { create } from '@coaction/svelte';
const store = create(source);
const count = store((state) => state.count);
const unsubscribe = count.subscribe((value) => {
console.log(value);
});Selector 调用返回 readable Svelte store。
Solid
import { create } from '@coaction/solid';
const store = create(source);
const count = store((state) => state.count);
console.log(count());Selector 结果是 Solid accessor。
共享模式说明
框架包可以包装 client mirror。即使同一个方法在 local store 中同步,只要 store 由 Worker 或 SharedWorker 创建,它就会返回 Promise;此时应 await mutation。
生成的 selector map 基于初始化期间已知的 schema。声明 record 内的动态 path 应使用显式 selector,不要期待 auto-selector map 自动增长。