React Alien Signals is a TypeScript library that provides hooks built on top of Alien Signals. It offers a seamless integration with React, ensuring concurrency-safe re-renders without tearing.
createSignal
.createComputed
.createEffect
and manage multiple effects with createSignalScope
.createAsyncComputed
and createAsyncEffect
.createComputedArray
and createComputedSet
.createEqualityComputed
.useSignal
, useSignalValue
, and useSetSignal
for seamless state management.Install react-alien-signals
and its peer dependency alien-signals
via npm:
npm install react-alien-signals alien-signals
Create a writable signal and use it within your components.
import React from "react";
import { createSignal, useSignal } from "react-alien-signals";
const countSignal = createSignal(0);
function Counter() {
const [count, setCount] = useSignal(countSignal);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
Derive reactive values based on other signals.
import React from "react";
import {
createSignal,
createComputed,
useSignalValue,
} from "react-alien-signals";
const countSignal = createSignal(1);
const doubleCount = createComputed(() => countSignal.get() * 2);
function Display() {
const double = useSignalValue(doubleCount);
return <div>Double Count: {double}</div>;
}
export default Display;
Run side effects in response to state changes and manage multiple effects.
import React from "react";
import {
createSignal,
createEffect,
useSignalScope,
} from "react-alien-signals";
const countSignal = createSignal(0);
function Logger() {
const scope = useSignalScope();
scope.run(() => {
createEffect(() => {
console.log("Count changed:", countSignal.get());
});
});
return null;
}
export default Logger;
Handle asynchronous state with async computed signals and effects.
import React from "react";
import {
createSignal,
unstable_createAsyncComputed,
unstable_useAsyncComputedValue,
} from "react-alien-signals";
const dataSignal = createSignal("initial");
const asyncData = unstable_createAsyncComputed<string>(async function* () {
yield dataSignal;
const response = await fetch(
`https://api.example.com/data?query=${dataSignal.get()}`,
);
const data = await response.text();
return data;
});
function AsyncDisplay() {
const data = unstable_useAsyncComputedValue(asyncData);
return <div>Async Data: {data ?? "Loading..."}</div>;
}
export default AsyncDisplay;
Manage reactive arrays and sets.
import React from "react";
import {
createSignal,
unstable_createComputedArray,
unstable_createComputedSet,
useSignalValue,
} from "react-alien-signals";
const numbersSignal = createSignal([1, 2, 3]);
const doubledNumbers = unstable_createComputedArray(
numbersSignal,
(itemSignal) => () => itemSignal.get() * 2,
);
const numberSetSignal = createSignal(new Set([1, 2]));
const doubledSet = unstable_createComputedSet(numberSetSignal);
function CollectionsDisplay() {
const doubled = useSignalValue(doubledNumbers);
const doubledSetValue = useSignalValue(doubledSet);
return (
<div>
<p>Doubled Numbers: {doubled.join(", ")}</p>
<p>Doubled Set: {[...doubledSetValue].join(", ")}</p>
</div>
);
}
export default CollectionsDisplay;
React Alien Signals provides several hooks to interact with signals:
useSignal(signal)
: Returns [value, setValue]
.useSignalValue(signal)
: Returns the current value (read-only).useSetSignal(signal)
: Returns a setter function (write-only).useSignalEffect(effectFn)
: Runs a side effect based on signal changes.useSignalScope()
: Manages effect scopes within a component.unstable_useAsyncComputedValue(asyncComputed)
: Retrieves the value from an async computed signal.unstable_useAsyncEffect(asyncEffectFn)
: Runs an asynchronous effect.Contributions are welcome! Please read the Contributing Guidelines before getting started.