@fluixi/反应
精致的信号,备忘录,效果和存储在TC39信号核心上:独立,不需要框架.
一个精细的反射系统 TC39 信号 图表:无故障,懒惰, 推-推. 它没有DOM依赖性,也没有框架依赖性,因此在 浏览器,在服务器上,或者自己操作.
特征
核心
- 信号、备忘录、效果: 细纹状态,衍生值,自动跟踪
- 存储: 在读取属性时嵌入的反应对象 实值 读取
- 资源: 与悬念结合的同步值
- 击打数字 :
batch()收藏会写成依赖者运行一次
超越基础
- 过渡数字 :
startTransition推迟非关键效果, 视图保持交互性 - 暂停和出错边界:作为平面值,任何视图层都可以被包起来
- A. 背景情况: 提供通话期间的值,不进行道具钻探
- 拥有者:明确所有权和处置权,所以一个图表完全崩溃了
- 被抛弃的原始人: 信号、资源和函数变体
- 可观察接口数字 :
Observable编号 :SubjectrxJS 形状代码 - 类型脚本: 全套安全和推断
安装
npm install @fluixi/reactive
快速启动
基本用途
import { signal, memo, effect, batch } from '@fluixi/reactive';
// Reactive state — call it to read, .set() to write
const count = signal(0);
// Derived state (cached)
const doubled = memo(() => count() * 2);
// Side effects (auto-tracking)
effect(() => {
console.log(`Count: ${count()}, Doubled: ${doubled()}`);
});
count.set(1); // Effect runs: "Count: 1, Doubled: 2"
// Batch multiple updates
batch(() => {
count.set(2);
count.set(3);
}); // Effect runs once: "Count: 3, Doubled: 6"
二重体形态
createSignal 返回与 a 相同的信号 [read, write] 组合,和 createMemo 编号 :
createEffect 为: memo 编号 : effect 原名为:
import { createSignal, createMemo, createEffect } from '@fluixi/reactive';
const [count, setCount] = createSignal(0);
const doubled = createMemo(() => count() * 2);
createEffect(() => console.log(count(), doubled()));
setCount(1);
signal 实值 访问者 createSignal 返回并附带设置器,因此读取为
无论是哪种方式,同一个电话。 他们互相跟踪,自由混合在一个模块中: 选择
无论哪一个读得更好, 并保持tiple 当你想要一半分开.
储存和资源
import { store } from '@fluixi/reactive/store';
import { resource } from '@fluixi/reactive/signal';
const cart = store({ items: [], total: 0 });
cart.total; // reading a property IS the reactive read
cart.set('total', 42); // only readers of `total` re-run
const user = resource(() => fetch('/api/me').then((r) => r.json()));
user(); // the value — suspends under a Suspense boundary
user.loading; // boolean
user.refetch();
过渡、背景和边界
import {
startTransition, useTransition,
createContext, useContext, provide,
createErrorBoundary, provideErrorBoundary,
} from '@fluixi/reactive';
// Non-blocking updates — `isPending` is a signal you can read while it runs
const [isPending, start] = useTransition();
start(() => setLargeDataSet(expensiveComputation()));
// Context: create it, provide a value for the duration of a call, consume inside
const ThemeContext = createContext({ mode: 'light' });
provide(ThemeContext, { mode: 'dark' }, () => {
useContext(ThemeContext); // { mode: 'dark' }
});
// Boundaries are values here, not components. A view layer wraps these into
// <ErrorBoundary> / <Suspense>; on their own they are plain functions.
const boundary = createErrorBoundary();
provideErrorBoundary(boundary, () => risky());
boundary.error(); // the thrown value, or undefined
boundary.reset();
调试
import { createDebounce, createDebouncedSignal, createDebouncedResource } from '@fluixi/reactive';
const [term, setTerm, controls] = createDebouncedSignal('', 300);
term(); // settles 300ms after the last write
controls.immediate(); // the value as written — bind the input to this one
controls.pending(); // a write is waiting (not the same as a request in flight)
controls.flush(); // settle now
// Search-as-you-type as one primitive: the query debounces, the fetch follows it,
// and an empty query doesn't fetch at all.
const [results, search] = createDebouncedResource('', (q) => fetchResults(q), { delay: 300 });
search.setQuery('fluix');
results.loading;
// Or debounce any function
const save = createDebounce((draft) => persist(draft), 500);
击打
写作会给其依附者留下污秽的印记并安排时间;备忘录会保持懒惰并重算 读取,所以图表是无故障的:没有看到半应用更新.
batch(() => {
a.set(1);
b.set(2);
c.set(3);
}); // dependents run once, after the batch closes
await flush(); // await the pending queue — mostly useful in tests
startTransition 是另一半: 它运行 fn 同步并捕获非纯度
所以昂贵的更新不会挡住
当前视图。 纯粹的计算仍然立即解决.
API 参考
核心 API
createSignal(initialValue, options?)- 创建反应状态createEffect(fn, options?)- 运行副作用createMemo(fn, initialValue?, options?)- 创建衍生状态batch(fn)- 批次多个更新untrack(fn)- 不跟踪读取信号createRoot(fn)- 创建处理根
过渡
startTransition(fn)- 将更新列为低优先级useTransition()- 轨迹过渡状态
边界
createSuspenseBoundary()编号 :provideSuspense(boundary, fn)- 作为值的自动边界createErrorBoundary()编号 :provideErrorBoundary(boundary, fn)- 作为值的错误边界trackResourcePromise(promise)- 将承诺与所附悬念一起登记
A. 背景情况
createContext(defaultValue)- 创建上下文provide(context, value, fn)- 在电话通话期间提供价值useContext(context)- 假设上下文
其他影响
createRenderEffect(fn)- 涂料前跑步,为DOM写作createComputed(fn)- 跑得很急 不像备忘录on(deps, fn, options?)- 明显依赖性
意见
observeReactiveNodes(observer)- 观察节点的建立、重算和处理。 @fluixi/devtools 所附带的内容; 未经观察, 每个节点花费一个无效检查 .
所有者管理
getOwner()- 获取当前被动的主人runWithOwner(owner, fn)- 和特定主人一起跑
名单
mapArray(list, fn)- 按身份键的地图;一行活过重排indexArray(list, fn)- 按指数键的地图keyArray(list, key, fn)- 由明确密钥键入地图
公用事业
createSelector(source, fn)- 键入选择器;只有修改了重运行的行createResource(fetcher, source?)编号 :resource(...)- 同步资源createStore(initial)编号 :store(initial)- 嵌入式反应物体createDeferred(source, options?)- 一个落后于负载的值createDebounce(fn, ms)编号 :createDebouncedSignal(initial, ms)编号 :createDebouncedResource(...)flush()- 等待待决效果队列unwrap(store)编号 :untrackStore(fn)- 从商店代理中逃出onCleanup(fn)编号 :disposeScope(owner)- 撕毁
文档
编译器内在
在编译的应用程序内 @fluixi/compiler这些原始人 $-前置双胞胎
不需要导入 : $signal, (中文(简体) ), $memo, (中文(简体) ), $effect, (中文(简体) ), $store, (中文(简体) ), $resource它们汇编到
以上调用,所以有一个反应图,行为上没有区别. 这个包
完全可以导入到此处的文档中, 这就是一个从未运行过
编译器需要.
绩效提示
- 批次相关的更新数字 :
batch(() => { a.set(1); b.set(2); })运行依赖者一次. - 昂贵更新的过渡数字 :
startTransition(() => list.set(compute()))在准备下一个视图时保持当前视图的交互性. - 纪念昂贵的部分: 备忘录需要节点 计算重于簿记.
- 缩小读取: 读取整个对象会订阅每个对象的写作. 到达 你的财产,或获得它.
- 按键列表数字 :
mapArray保持一行的节点穿过重排顺序;indexArray重建他们.
大楼
nx build reactive
运行测试
nx test reactive
许可证
麻省理工学院
贷项
图表执行 TC39 信号 型号。 人类基因组很亏欠前作: 精细原始物和排程的固态JS, 过渡反应和悬念为 概念,用于反应设计的Vue 3。 这些都不是在这里发明的.