React.js state management using signals
Tags: react, signals, preact, javascript
Published: 2022-09-21 05:24:29

A signal is an object that has a value and can be observed for changes. It is similar to a state, but it is not bound to a component. It can be used to share data between components. It updates the components when the signal changes and updates the UI without re-rendering the whole component.

{% youtube https://www.youtube.com/watch?v=Y86kgiUC3n0&autoplay=1&mute=1 %}


This lets us skip all of the expensive rendering work and jump immediately to any components in the tree that access the signal's value property.

In this article, I'll be using signals with React.

#### Installation

```bash
npm i @preact/signals-react
```
---
#### Create a signal

We can create state(signal) using signal function, signal function takes default `signal(value)` as an parameter and returns Proxy object. The value of the signal can be accessed using the `signal.value` property. We can also set the value of the signal using `signal.value = newValue`.

```jsx
import { signal } from "@preact/signals-react";
const count = signal(0);
```
---

#### Counter Component

```jsx
import React from "react";
import { signal } from "@preact/signals-react";

const count = signal(0);
const Counter = () => <button onClick={() => count.value++}>{count}</button>;
```

###### NOTE: React Hooks can only be called inside the root of the component, Signal can be used outside of a component.

---

#### Effect

We don't have to pass dependencies array like the useEffect hook. It'll automatically detect dependencies and call effect only when dependencies change.

```jsx
import React from "react";
import { signal, effect } from "@preact/signals-react";

const count = signal(0);
const Counter = () => {
  effect(() => console.log(count.value));
  return <button onClick={() => count.value++}>{count}</button>;
};
```
---

### Advanced Usage

When working with signals outside of the component tree, you may have noticed that computed signals don't re-compute unless you actively read their value.

```jsx
const count = signal(0);
const double = computed(() => count.value * 2);

const Counter = () => {
  effect(() => console.log(count.value));
  return (
    <div>
      <h1>{double}</h1>
      <button onClick={() => count.value++}>{count}</button>
    </div>
  );
};
```

#### Live Demo: [Counter Demo](https://stackblitz.com/edit/react-signal-for-state-management-sr6tqk?file=App.tsx)

---

Thank you for reading 😊

Got any questions or additional? please leave a comment.

---

### Must Read If you haven't
{% link https://dev.to/devsmitra/how-to-create-the-app-using-jsx-without-react-k08 %}
{% link https://dev.to/devsmitra/useasync-hook-with-cache-5817 %}
{% link https://dev.to/devsmitra/how-to-cancel-javascript-api-request-with-abortcontroller-36cm %}
{% link https://dev.to/devsmitra/13-typescript-utility-a-cheat-sheet-for-developer-ab3 %}


### Catch me on
{% user devsmitra %}
<p>
{% cta https://www.youtube.com/@bit-buddy?sub_confirmation=1 %} Youtube {% endcta %}
{% cta https://github.com/devsmitra %} Github {% endcta %}
{% cta https://www.linkedin.com/in/rahul-sharma-18b8b374 %} LinkedIn {% endcta %}
{% cta https://devsmitra.medium.com %} Medium {% endcta %}
{% cta https://stackblitz.com/@devsmitra %} Stackblitz {% endcta %} {% cta https://devsmitra.hashnode.dev %} Hashnode {% endcta %}
{% cta https://hackernoon.com/u/devsmitra %} HackerNoon {% endcta %}
</p>