https://github.com/arif-rachim/react-hook-signal
React-Hook-Signal is a tiny library, less than 1kb. It helps you integrate Signal with your React components easily.
https://github.com/arif-rachim/react-hook-signal
react reactjs typescript-library typescript-react webcomponent
Last synced: 8 months ago
JSON representation
React-Hook-Signal is a tiny library, less than 1kb. It helps you integrate Signal with your React components easily.
- Host: GitHub
- URL: https://github.com/arif-rachim/react-hook-signal
- Owner: arif-rachim
- License: mit
- Created: 2024-04-10T04:41:19.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-29T08:26:01.000Z (12 months ago)
- Last Synced: 2025-04-12T02:05:51.459Z (8 months ago)
- Topics: react, reactjs, typescript-library, typescript-react, webcomponent
- Language: TypeScript
- Homepage:
- Size: 56.1 MB
- Stars: 5
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README

[](http://commitizen.github.io/cz-cli/)
[](https://codecov.io/gh/arif-rachim/react-hook-signal)
[](https://github.com/arif-rachim/react-hook-signal/actions/workflows/node.js.yml)
[](https://bundlephobia.com/package/react-hook-signal@latest)
> React-Hook-Signal is a tiny library, less than 1kb. It helps you integrate Signal with your React components easily.
### Installation
```bash
npm install react-hook-signal signal-polyfill
```
## What are Signals?
The TC39 Proposal for Signals in JavaScript aims to establish a mechanism for components to communicate effectively. This proposal includes a polyfill for prototyping purposes.
### Understanding Signals
- Refer to https://eisenbergeffect.medium.com/a-tc39-proposal-for-signals-f0bedd37a335 for detailed explanation.
- Explore the proposal repository: https://github.com/proposal-signals/proposal-signals
Once adopted, JavaScript will have a native signaling system, referred to as `Signal` throughout this guide.
### How signal can efficiently re-render react component

In React components, re-rendering starts at the component's beginning and extends to the end of the JSX element. Signal usage allows precise re-rendering, boosting performance and simplifying development without the need for memoization or useCallback functions.
## Why choose React-Hook-Signal?
- It's straightforward: Just React and Native Signal, no extra babel plugin needed.
- Enjoy full TypeScript support for an improved Developer Experience.
- Flexibility is key: Opt-in for integration in your React project, seamlessly blending state and signal.
- It's incredibly lightweight, clocking in at less than 1kb
## Steps to Integrate Signals with React
### STEP 1: Rendering Signal Values:
- Utilize `notifiable` components provided by react-hook-signal.
- `notifiable` components accept standard HTML attributes, `Signal`, and `Lambda` for detecting dependency changes.
Example:
```tsx
// Global.tsx
import {Signal} from "signal-polyfill";
import {JSXAttribute} from "react-hook-signal";
export const count = new Signal.State(0)
export const renderCount = new Signal.Computed(() => {
return
Count {count.get()}
})
```
The fastest way to integrate these `Signals` is to use the `notifiable` components.
```tsx
import {count,renderCount} from "./GlobalSignals.tsx";
// here we are importing react-hook-signal:notifiable
import {notifiable} from "react-hook-signal";
export function App() {
return <>
{/* When user click button it will update the state */}
count.set(count.get() + 1)}>Click here
{/* Following line will get auto update when user click button*/}
{renderCount}
>
}
```
`notifiable` component attributes is not only capable of accepting the `Signal` type but also can receive `Lambda`
> Lambda is a callback that's able to listen for changes in the signals it depends on.
```tsx
import {count} from "./GlobalSignals.tsx";
import {notifiable} from "react-hook-signal";
export function App() {
return <>
{/* When user click button it will update the state */}
count.set(count.get() + 1)}>Click here
{/* Following line will get auto update when user click button*/}
{() => {
return
Count {count.get()}
}}
>
}
```
### STEP 2: Observing Signal Changes
- Use the `useSignalEffect` hook to listen for changes in Signal.
- This hook accepts a callback that reads the final signal value and can optionally return a cleanup function.
#### Important Note:
- `useSignalEffect` doesn't automatically re-render the component. Use React.useState to trigger a re-render.
Example:
```tsx
import {count} from "./GlobalSignals.tsx";
import {useSignalEffect} from "react-hook-signal";
import {useState} from "react";
export function App() {
const [countState,setCountState] = useState(count.get())
useSignalEffect(() => {
// Here, within the useSignalEffect hook, I can listen for updates on any Signal.State or Signal.Computed
setCountState(count.get())
})
return
{/* When user click button it will update the state */}
count.set(count.get() + 1)}>Click here
{/* Following line will be updated because of countState updated*/}
{countState}
}
```
### STEP 3: Creating Signals in React Components:
- `useSignal` is a hook that creates `Signal.State`, and `useComputed` is a hook that creates `Signal.Computed`.
- These hooks generate signals that are linked to the component's lifecycle.
- To create a `Signal.State`, simply provide a constant value as a parameter when calling `useSignal`.
- To create a `Signal.Computed`,simply provide a `Lambda` that returns the result of a dynamic computation.
Example :
```tsx
import {notifiable, useSignal, useComputed} from "react-hook-signal";
export function App() {
// creating Signal.State count
const count = useSignal(0);
// creating Signal.Computed countString
const countString = useComputed(() => (count.get() * 2).toString());
// creating Signal.Computed style
const style = useComputed(() => {
const isEven = count.get() % 2 === 0;
return {
background: isEven ? 'white' : 'black',
color: isEven ? 'black' : 'white'
}
})
// creating Signal.Computed text
const text = useComputed(() => {
const isWhite = style.get().background === 'white'
return
{isWhite ? 'Background is White' : 'Background is Black'}
})
return
{/* When user click button it will update the state */}
count.set(count.get() + 1)}>Click here
{/* Following line will never get auto update*/}
{countString.get()}
{/* Following line will get auto update when user click button*/}
{countString}
{/* Following line will get auto update when user click button*/}
{text}
}
```
### STEP 4: Encapsulate any Component with a Notifiable :
- Use `Notifiable` component to wrap any React Functional or Class Component
- A React component encapsulated within the `Notifiable` component will inherently enable its properties and children to utilize `Lambda` expressions or `Signals` seamlessly
Example :
```tsx
import {Notifiable} from "react-hook-signal";
export function App() {
const count = useSignal(0);
return
{/* When user click button it will update the state */}
count.set(count.get() + 1)}>Click here
{/* Following line will be updated because of count updated*/}
{
return count.get() + ' Times'
}}>
}
function MyComponent(props:{title:string}){
return
Here is the title {props.title}
}
```
### Summary
The integration of `Signal` into the React application can be done in various ways tailored to the needs and complexity of the app.