Signals in React, What’s the Fuss About?

Mohamed Eltahawy
Nov 13, 2023
6 min read
post_comment0 Comments
post_like0 Likes

If you’ve been following the React development scene, you’ve probably heard about Signals – a new method to manage application states. This new feature has been generating a lot of buzz among React developers lately, but what’s all the fuss actually about?

In this article, we’ll explore the reasons why React developers are so interested in Signals and what makes it a valuable addition to any React project. Whether you’re a seasoned React developer or just getting started, understanding Signals will give you a leg up in your development work.

#What is Signals?

Signals is a performant state management library for managing application state, working as objects that have a .value property. Signals can track when their value is accessed and “subscribe” the component that accessed the value to them. Whenever there’s a change in the signal value, the subscribed component parts will also be automatically updated.

What’s critical here is that the signal object will trigger an update only in the elements of the component tree that are accessing the signal’s value. As thePreact teamexplains:

“Instead of passing a value directly through the component tree, we pass a signal object containing the value (similar to a ref). When a signal’s value changes, the function stays the same. As a result, signals can be updated without re-rendering the components they’ve been passed through since components see the signal and not its value.”

To ensure that Signals work as fast as possible, Preact built it on the following principles:

  • **Lazy by default **– only signals that are currently used by any component are observed and updated. Disconnected signals, meanwhile, will be automatically skipped.

  • Optimal updates– if a signal’s value hasn’t changed, components and effects that use that value won’t be updated even if the signal’s dependencies have changed.

  • Optimal dependency tracking– the framework itself keeps track of the components that depend on a given signal, unlike the React Hooks architecture which relies on dependency arrays.

  • Direct access– accessing a signal’s value in a component automatically subscribes to updates without the need for selectors or hooks.

Signals are also very light – they will only add around 1.6 kB to your application bundle. Plus, they can be used inside or outside of components (unlike hooks) and even work alongside class components.

#How to install the Signal function

To use Signals, you need to import the library into your component, create a signal, and subscribe to receive updates whenever the state changes. To install the library, type:

1npm install @preact/signals
2

or

1npm install @preact/signals-react
2

To show how Signal works in an example, let’s try using it to manage the “count” value. We want the signal value to be updated whenever the count value changes. The code will then look like this:

1import { signal } from "@preact/signals-react";
2
3const count = signal(0);
4
5const App = () => (
6  <div> 
7	<button onClick={() => count.value++}>{count}</button>
8  </div>
9);
10

To subscribe to the “count” signal in another component, simply move the count signal to a separate file and then import the signal:

1import { count } from "./signals";
2
3function AnotherComponent() {
4  return (
5    <div>
6      <p>Current Count: {count}</p>
7    </div>
8  );
9}
10

And that’s it – Signal will observe the subscribed component from now on, and will automatically update the relevant component part if it notices any changes.

#Why are people so interested in Signals?

React Hooks has been used to manage application state for a few years now, so why should you now switch to using Signals for the task? The main reason here is that Signals can be useful for your project in a few ways.

The biggest benefit is that Signals can handle updates much faster and smoother than React Hooks. Rather than re-rendering the whole component (which might take time, especially with complex applications), Signals will jump immediately to the relevant parts of a component and update only those.

Since Signal can automatically detect dependencies and changes in them too, so there’s no need to set dependencies arrays.

To name of few more benefits of working with Signals:

  • The signal reference does not change as the application grows, so Signals can be used to write business logic for both small and complex apps.

  • Signal has deep integrations with both React and Preact, hence they don’t need any selectors, wrapper functions, or similar.

  • Components can subscribe to a signal just by reading the .value property (so there’s no need to use selectors for this task).

#Limitations and drawbacks of Signals in React

With all of its features, Signals can make managing the states of React applications easier and more efficient. However, as a new functionality, Signals still has a few limitations, such as the following.

#Performance overhead

When using Signals there can be a performance overhead associated with accessing and updating state. This is especially true for large, complex applications with many states to manage. To mitigate this, it’s important to keep your state normalized and to use memoization wherever possible.

#Debugging complexity

While Signals can simplify state management in some ways, it can also add complexity to your code when it comes to debugging. Because states are managed through a centralized store, it can be harder to trace the flow of data and track down bugs when they occur.

#Scalability

Finally, it’s worth noting that Signals may not be the best choice for extremely large, complex applications. As your application grows in size and complexity, you may find that you need more advanced state management tools like Redux to effectively manage states.

#Best practices for using Signals

To help you make the most of the Signals library, we have also prepared a few best practices you should follow while using the library:

  • Keep your state minimal and well-organized– Try to keep each signal focused on a specific part of the state to avoid overloading them with data rather than asking each one to manage multiple parts.

  • Use signals only where needed– You might be tempted to try and use signals for every piece of state in your application, but this might lead to performance issues. What we would recommend here is to only use signals when you need to share data about the state between different parts of your application. For local app state that doesn’t need to be shared, use React’s built-in useState() hook instead.

  • Keep your components small and focused– Creating “all-in-one” components that try to handle several tasks can make the state harder to manage. A much better idea is to break your UI down into smaller, more focused components that each manage a specific piece of state.

#Conclusion

Signals is a relatively new library in the React ecosystem, but it’s quickly gaining popularity for its ability to simplify and streamline state management. Its unique approach, using signals and actions to update and share state, has caught the attention of many React developers who are looking for a more efficient and organized way to manage application states.

However, while Signals has many benefits, it’s important to note that it’s not a silver bullet and might not work for all state management needs. For projects that require sharing states between different parts of the application, Signals can be a powerful tool for simplifying state management and reducing the complexity of your code.

You are not logged in.