MOME, can we get SolidJS
No. There is SolidJS at home.
SolidJS at home:
pnpm add react-signal-state
import { useSignalState } from "react-signal-state";
import { signal } from "@preact/signals-core";
const counter = signal(0);
setInterval(() => (counter.value = counter.value + 1), 1000);
function Counter() {
const $ = useSignalState({ count: counter });
return <div>{$.count}</div>;
}
import { createSignalStore } from "react-signal-state/store";
import { signal, computed } from "@preact/signals-core";
const store = createSignalStore(({ initialName }: { initialName: string }) => {
const name = signal(initialName);
const showedName = computed(() => (name.value === "React" ? "Solid" : name.value));
return {
$: { name, showedName },
changeName: (newName: string) => (name.value = newName),
};
});
function App() {
return (
<store.provider initialName="React">
<Name />
</store.provider>
);
}
function Name() {
const { $, changeName } = store.useSignalState();
return (
<div>
<input value={$.name} onChange={(e) => changeName(e.target.value)} />
<div>{$.showedName}</div>
</div>
);
}
Making complex state in React is hard. State is attached to the component tree, and it's difficult to model complex and shared state between components.
Hooks like useState
and useContext
are great, but have a mental model that is hard (or tedious) to scale.
That why many state solutions exist for React, like Redux, Tanstack, Jotai and Zuztand. or even similar alternatives or compilers, like Preact and Million.js. It's a fundamental problem in a great ecosystem.
Event thought the great advances in developer experience, there is space to improve. The idea of this library, at the current state, is to explore different patterns that seems to be more unexplored, using Signals and ideas from SolidJS.
-
Smart subscriptions: Instead of a selection like pattern, like:
const stateA = useStore((state) => state.a);
This library tracks automatically witch signal is accessed and subscribe to it, using a proxy.
function WillOnlyRunOnAChange() { const $ = useSignalState({ a: signal(1), b: signal(2) }); console.log($.a); // Will only run when $.a changes. }
-
Great composition: Signals are already composable. This library also allows to compose via context.
const storeA = createSignalStore(() => { const a = signal(1); return { $: { a } }; }); const storeB = createSignalStore(() => { const { a } = storeA.useStore(); const b = computed(() => a.value + 1); return { $: { b } }; });
-
Incredible small.
-
Supports SSR. Doesn't need hydration helpers, it just works.
-
Does not require any code transformation.
- Should this library use
@preact/signals-core
? Is there another signal library that is better? - This readme probably should be rewritten.
- Ths
useStore
insidecreateSignalStore
is weird. But is it ilegal? See if React'suse
is more appropriate. - Tracking with effects is hacky. An implementation with an API like
Watcher
in the Signal Proposal might be preferable.