@embra/反应
一种轻量级,可堆肥和明显的反应系统.
特征
完全反应 没有代理,没有魔法.
它不将数值转换为 Object.defineProperty 也没有 Proxy. 将一切保持为平版JavaScript值使得与其他库一起工作更加容易,并方便JavaScript引擎优化.
import { writable, readable, type Readable } from "@embra/reactivity";
const count$ = writable(0);
count$.set(1);
const [count2$, setCount] = readable(0);
setCount(1);
明确的反应。 没有隐藏的依赖,没有惊喜.
与基于信号的库不同, @embra/reactivity 不自动跟踪依赖关系。 您明确定义了观看的内容以及如何对变化作出反应。 这一点比较容易说明依赖性,也减少了复杂隐含依赖性计算的成本.
使用类似回放钩子的API,计算可以是更能与一般非回放函数相兼容的纯函数.
import { writable, derive } from "@embra/reactivity";
const count$ = writable(0);
const isPositive = (value: number): boolean => value > 0;
const positiveCount$ = derive(count$, isPositive);
可使用 get 内 compute 或者说 watch。 。 。 .
import { writable, compute, watch } from "@embra/reactivity";
const count$ = writable(0);
const doubleCount$ = compute(get => get(count$) * 2);
watch(get => {
const count = get(count$);
console.log(`Count is ${count}, double is ${get(doubleCount$)}`);
});
QQ零成本所有制模式. 类型安全生命周期管理.
实际上,我们在反应库中遇到的最大问题之一是反应值的生命周期管理. 单位 @embra/reactivity,反应依赖性被弱地引用,所以一般不需要手动处理. 然而,明确的生命周期管理仍然是避免出乎意料的行为的良好做法.
@embra/reactivity 提供零成本所有权模式,允许您创建具有明确所有权的被动值.
默认情况下,创建的活性值与类型 OwnedReadable 或者说 OwnedWritable,它暴露一个 dispose() 清除用户的方法。 当将被动值传递到其他模块时,您可以使用 Readable 或者说 Writable 类型来隐藏 dispose() 方法,确保不意外地处理该值.
import { writable, readable, type Readable, type OwnedWritable } from "@embra/reactivity";
const count$: OwnedWritable<number> = writable(0);
count$.set(1);
// Hide the setter by typing
function logCount(count$: Readable<number>) {
count$.subscribe(console.log);
// @ts-expect-error
count$.set(2);
}
logCount(count$);
// Hide the setter in runtime
const [count2$, setCount] = readable(0);
setCount(1);
// @ts-expect-error
count2$.set(2);
国家与行动的灵活抽象.
在"Flux reductioner"模式的年代,我们经常使用单商店来持有状态和动作来改变状态. 这对关于该州的推理是不错的,但也引入了许多锅炉板代码.
后来,引入了状态和动作粘合在一起的模式,比如 redux-actions。 。 。 . @embra/reactivity 通过简单而灵活地抽象国家与行动,进一步推进这一步.
在下面的例子中,我们创建了Writable count$ 这看起来像一个 Writable<number>,但内部来源于更大的应用状态 appState$。这使其他模块依赖于 Writable<number> 并不知道申请状态的细节.
import { writable, derive, toWritable } from "@embra/reactivity";
import { trace } from "@embra/reactivity/debug";
const appState$ = writable({
count: 0,
user: null,
});
const count$ = toWritable(
derive(appState$, state => state.count),
count => appState$.set({ ...appState$.value, count }),
);
// when debugging, you can trace the reactive value
trace(count$);
QQ 控制更新的调度机制 .
@embra/reactivity 包括调度器机制和内置调度器,允许您在被动更新处理时进行控制.
这对批量更新和推迟计算很有用.
import { writable, MicrotaskScheduler } from "@embra/reactivity";
const rapidChangeCount$ = writable(0);
rapidChangeCount$.reaction(console.log, MicrotaskScheduler);
count$.set(1);
count$.set(2);
await Promise.resolve();
// Logs "2" once after a microtask tick, reducing unnecessary computations.
您也可以轻松提供您自定义的调度器功能 .
import { writable, asyncScheduler } from "@embra/reactivity";
const MicrotaskScheduler = asyncScheduler(flush => Promise.resolve().then(flush));
const AnimationFrameScheduler = asyncScheduler(requestAnimationFrame);
框架不可知论。 头等支持回放.
@embra/reactivity 被设计为框架不可知论。 它可用于支持JavaScript的任何框架或库. 它还为React提供一等支持.
- 作为组件道具的活性值只是简单而高效.
value=:Readablevalue+ 键onChange=:Writablestate+ 键action=:toWritable(derive(rootState$, selector), action)(见 国家与行动(中文(简体) )
- 在道具下传回反应值时,可以避免出很多回放. 您只需要订阅组件中实际使用的活性值 .
import { writable } from "@embra/reactivity";
import { useValue, useDerived, useCombined } from "@embra/reactivity/react";
const count$ = writable(0);
function Counter({ count$ }) {
const count = useValue(count$);
const countDouble = useDerived(count$, count => count * 2);
return (
<div>
<button onClick={() => count$.set(count - 1)}>-</button>
<span>{count}</span>
<button onClick={() => count$.set(count + 1)}>+</button>
<span>{countDouble}</span>
</div>
);
}
小捆绑大小。 注重表现和简洁.
安装
npm add @embra/reactivity
调试
追踪
@embra/reactivity 页:1 trace() 函数帮助调试反应值和手表。 它跟踪价值和依赖性的变化,并将其记录到控制台.
import { writable, watch } from "@embra/reactivity";
import { trace } from "@embra/reactivity/debug";
const count$ = writable(0);
// trace a reactive value
trace(count$);
// trace a watch function
watch(trace(get => get(count$)));
count$.set(1);
Chrome Devtools 自定义格式
@embra/reactivity 支持 Chrome DevTools 软件 自定义格式化。您可以通过检查 DevTools 常规设置中的“ Console” 部分中的“ 可启用自定义格式化器” 选项来启用它.
它默认在开发中启用。 您也可以通过呼叫手动启用 customFormatter()。 。 。 .
import { customFormatter } from "@embra/reactivity/debug";
customFormatter();