Gathering detailed insights and metrics for @preact/signals-react
Gathering detailed insights and metrics for @preact/signals-react
Gathering detailed insights and metrics for @preact/signals-react
Gathering detailed insights and metrics for @preact/signals-react
@preact/signals-react-transform
Manage state with style in React
@preact-signals/safe-react
Manage state with style in React
@quilted/react-signals
Utilities for working with Preact signals.
@preact-signals/query
A reactive utility for React/Preact that simplifies the handling of data fetching and state management. Powered by Preact Signals, it provides hooks and functions to create reactive resources and manage their state seamlessly.
Manage state with style in every framework
npm install @preact/signals-react
Typescript
Module System
Node Version
NPM Version
97.4
Supply Chain
99
Quality
91.8
Maintenance
100
Vulnerability
100
License
@preact/signals-react@3.0.1
Published on 13 Jan 2025
@preact/signals@2.0.1
Published on 13 Jan 2025
@preact/signals@1.3.2
Published on 13 Jan 2025
@preact/signals-react-transform@0.5.1
Published on 02 Jan 2025
@preact/signals-react@3.0.0
Published on 02 Jan 2025
@preact/signals-react-transform@0.5.0
Published on 17 Dec 2024
TypeScript (94.54%)
JavaScript (5.38%)
Dockerfile (0.06%)
Shell (0.03%)
Total Downloads
4,790,490
Last Day
22,661
Last Week
96,769
Last Month
391,462
Last Year
4,057,066
3,902 Stars
806 Commits
97 Forks
26 Watching
32 Branches
55 Contributors
Minified
Minified + Gzipped
Latest Version
3.0.1
Package Id
@preact/signals-react@3.0.1
Unpacked Size
123.19 kB
Size
24.95 kB
File Count
25
NPM Version
10.8.2
Node Version
18.20.5
Publised On
13 Jan 2025
Cumulative downloads
Total Downloads
Last day
-6%
22,661
Compared to previous day
Last week
-18.1%
96,769
Compared to previous week
Last month
18.4%
391,462
Compared to previous month
Last year
470.5%
4,057,066
Compared to previous year
2
1
Signals is a performant state management library with two primary goals:
Read the announcement post to learn more about which problems signals solves and how it came to be.
1npm install @preact/signals-react
The React integration can be installed via:
1npm install @preact/signals-react
We have a couple of options for integrating Signals into React. The recommended approach is to use the Babel transform to automatically make your components that use signals reactive.
Install the Babel transform package (npm i --save-dev @preact/signals-react-transform
) and add the following to your Babel config:
1{ 2 "plugins": [["module:@preact/signals-react-transform"]] 3}
This will automatically transform your components to be reactive. You can then use signals directly inside your components.
1import { signal } from "@preact/signals-react"; 2 3const count = signal(0); 4 5function CounterValue() { 6 // Whenever the `count` signal is updated, we'll 7 // re-render this component automatically for you 8 return <p>Value: {count.value}</p>; 9}
See the Readme for the Babel plugin for more details about how the transform works and configuring it.
useSignals
hookIf you can't use the Babel transform, you can directly call the useSignals
hook to make your components reactive.
1import { useSignals } from "@preact/signals-react/runtime"; 2 3const count = signal(0); 4 5function CounterValue() { 6 useSignals(); 7 return <p>Value: {count.value}</p>; 8}
If you need to instantiate new signals or create new side effects on signal changes inside your components, you can use the useSignal
, useComputed
and useSignalEffect
hooks.
1import { useSignal, useComputed, useSignalEffect } from "@preact/signals-react"; 2 3function Counter() { 4 const count = useSignal(0); 5 const double = useComputed(() => count.value * 2); 6 7 useSignalEffect(() => { 8 console.log(`Value: ${count.value}, value x 2 = ${double.value}`); 9 }); 10 11 return ( 12 <button onClick={() => count.value++}> 13 Value: {count.value}, value x 2 = {double.value} 14 </button> 15 ); 16}
Components rendered using SSR APIs (e.g. renderToString
) in a server environment (i.e. an environment without a global window
object) will not track signals used during render. Components generally don't rerender when using SSR APIs so tracking signal usage is useless since changing these signals can't trigger a rerender.
The React adapter ships with several optimizations it can apply out of the box to skip virtual-dom rendering entirely. If you pass a signal directly into JSX, it will bind directly to the DOM Text
node that is created and update that whenever the signal changes.
1import { signal } from "@preact/signals-react"; 2 3const count = signal(0); 4 5// Unoptimized: Will trigger the surrounding 6// component to re-render 7function Counter() { 8 return <p>Value: {count.value}</p>; 9} 10 11// Optimized: Will update the text node directly 12function Counter() { 13 return ( 14 <p> 15 <>Value: {count}</> 16 </p> 17 ); 18}
To opt into this optimization, simply pass the signal directly instead of accessing the .value
property.
Note The content is wrapped in a React Fragment due to React 18's newer, more strict children types.
This version of React integration does not support passing signals as DOM attributes. Support for this may be added at a later date.
Using signals in render props is not recommended. In this situation, the component that reads the signal is the component that calls the render prop, which may or may not be hooked up to track signals. For example:
1const count = signal(0); 2 3function ShowCount({ getCount }) { 4 return <div>{getCount()}</div>; 5} 6 7function App() { 8 return <ShowCount getCount={() => count.value} />; 9}
Here, the ShowCount
component is the one that accesses count.value
at runtime since it invokes getCount
, so it needs to be hooked up to track signals. However, since it doesn't statically access the signal, the Babel transform won't transform it by default. One fix is to set mode: all
in the Babel plugin's config, which will transform all components. Another workaround is put the return of the render prop into it's own component and then return that from your render prop. In the following example, the Count
component statically accesses the signal, so it will be transformed by default.
1const count = signal(0); 2 3function ShowCount({ getCount }) { 4 return <div>{getCount()}</div>; 5} 6 7const Count = () => <>{count.value}</>; 8 9function App() { 10 return <ShowCount getCount={() => <Count />} />; 11}
Similar issues exist with using object getters & setters. Since the it isn't easily statically analyzable that a getter or setter is backed by a signal, the Babel plugin may miss some components that use signals in this way. Similarly, setting Babel's plugin to mode: all
will fix this issue.
MIT
, see the LICENSE file.
No vulnerabilities found.
No security vulnerabilities found.