React Hooks are dead and it's official! hooks have always been the traditional way of handling state and running side-effects in our React components and for a while, they made it easy for React. However old things shall pass away and all things will become new. This post is just to say grace for Hooks before we usher it into the great beyond. Signals are a concept that has been around in other frameworks for a while but they just got added to react and since then signals have blown up in popularity and usage. All major frontend frameworks have their implementation of signals.
You now have to ask the question, why are signals so popular and why is everyone using them? You see signals provide another layer of abstraction on top of your framework and in this case React, signals take care of tracking a variable state, updating it, and rerendering your components for you. Signals also allow us to write reactive code which makes it very easy to run side-effects without having to manage any dependency array because that has already been done for you. They can reduce your reliance on useMemo
and useCallback
due to their lazy nature and dependency tracking feature.
So we have established that signals are the new knight in shining armor, well let's get on with how that is of any use to us. In today's post, I'm going to show you how to get started with using signals in your react project, I'm going to keep the react application as simple as possible, and we will be considering the following talking points
- Setup React Project Setup/Walkthrough
- Installing and using signals
- Computed Signals
- Side Effects with Signals
- Will signals replace hooks?
Project Setup
The setup for this project is simple, I'm going to assume that you already know how to set up a React project so I'm going skip that however let me show you what our overall project structure looks like
src-----/assets
|---/components
|---/navigation
|---/pages
|---/App.jsx
|---/helper.js
|---/index.css
|---/main.jsx
The only folders we will concern ourselves with are the components
folder, the pages
folder and the helper.js
file, the components
folder has two three components inside, a Navbar
component, a Footer
component and Post
component.
src---/components/Footer.jsx
|----------/Navbar.jsx
|----------/Post.jsx
----/pages/index.jsx
|-----/post/index.jsx
|----/components/post_detail.jsx
----/helper.js
The pages
folder has an index.jsx
file which is the home page, and a folder, post
which in turn has its own index.jsx
file, and a components
folder which has just one component inside, a post_detail.jsx
file. The helper.js
file will export functions that we will use inside our application.
Installing and using signals
To install signals in your project spin up a terminal and run the following command;
npm i preact/signals-react
This installs the preact signal library for react, let's go ahead and start creating signals. Let's edit the helper.js
file.
// src/helper.js
import { signal } from "@preact/signals-react";
const Posts = signal([
{
id: 1,
title: "Introduction to Javascript",
published: "10th May 2020",
tags: ["javascript", "programming"],
readingTime: 3,
description:
"Lorem ipsum dolor sit amet c....",
author: "Kinanee Samson",
},
{
id: 2,
title: "Introduction to Python",
published: "8th March 2021",
tags: ["python", "programming"],
readingTime: 3,
description:
"Lorem ipsum dolor sit amet c....",
author: "Kinanee Samson",
},
]);
export const getPosts = () => {
return Posts;
};
I've imported the signal
from preact/signals-react
and this is a function that takes in a single value as its argument and returns a signal for us. I just use the function here to wrap our array of posts then we store the result inside a variable Post
. Then we create a function getPosts
which just returns the Posts
signal we've created, and then we export the getPosts
function from this file so we can use it in other files. Now let's head back to the index file to make use of these Posts.
// src/pages/index.jsx
import Navbar from "../../components/navbar";
import Footer from "../../components/footer";
import Post from "../../components/post";
import { getPosts } from "../../helper";
const posts = getPosts();
const Home = () => {
return (
<section>
<Navbar />
<main>
{posts.value.map((post, index) => (
<Post
key={index}
title={post.title}
description={post.description}
author={post.author}
published={post.published}
readingTime={post.readingTime}
id={post.id}
/>
))}
</main>
<Footer />
</section>
);
};
export default Home;
If you observe there's no use of any useState
or useEffect
statement to do any side effect or any complex state management. This is because like I stated earlier Signals
abstracts all of that away from you and handles state management and reactivity by default. You can see how elegant our component looks and the fact that the signal will only also take care of rerendering components. Each signal has a value
property defined on it, it is on this value property that the current value of that signal is stored. Whenever you access the value property on a signal you are subscribing to that signal. Whenever the value
on the signal is updated your component will automatically be rerendered to display the current value of that signal.
Computed Signals
Now let's write the function for retrieving an individual post. First, we'll edit the helper
file.
// src/helper.js
//....cont'd
export const getPost = (id) => {
return signal(Posts.value.find((post) => post.id === Number(id)));
};
The function above accepts an id
argument then we use the id
to search through the Post
signals to return the post with an id that matches the id
we passed in, and then we return that value/post as a signal and this Pattern is known as computed signals
. A computed signal is a signal whose value depends on another signal. Computed signals are read-only and they also manage their dependencies by default only updating when the underlying signal or dependency has updated. Now let's make use of this in our component.
// src/pages/post/index.js
import Navbar from "../../components/navbar";
import Footer from "../../components/footer";
import PostDetails from './components/post-details'
import { getPost } from "../../helper";
import { useParams } from "react-router-dom";
const Post = () => {
const {id} = useParams()
const post = getPost(id)
return (
<section>
<Navbar links={links} title="todo-blog" />
<main className="body">
{post && (<PostDetails
author={post.value.author}
content={post.value.content}
published={post.value.published}
readingTime={post.value.readingTime}
title={post.value.title}
/>)}
</main>
<Footer company_name="Netcreed" />
</section>
);
};
export default Post;
Side Effects
I know you are wondering how on earth am I going to handle side effects in my components. If for any reason you have to run some side effects then you can use the effect
function from preact signals-react.
// src/pages/post/index.js
// ...contd
import {effect} from '@preact/signals-react'
const Post = () => {
const {id} = useParams()
const post = getPost(id)
effect(() => console.log(post.title))
// ...contd
}
export default Post
The effect function accepts a callback function as its argument, now anytime the post changes the title of the post is going to be logged to the console, you can take advantage of this to run side-effects in your components.
Will signals replace Hooks
Will signals replace Hooks? This is an interesting question to ask. Personally in my humble opinion signals will replace some hooks but not all hooks, as you can observe from the code examples we considered above you can see that things like state management and component side effects can be managed with signals which eliminate the need to use hooks for handling such situations. Even some basic implementations of useCallback and useMemo hooks can be replaced with signals. However, we can only go so far, for more complex useCallback and useMemo hooks we will still stick to hooks.
Although signals are quite new to React expect them to get so much better with time but for now this is what we have. At the end of the day, it might still boil down to the developer and what they'd prefer to use. Do you think that signals have just made hooks obsolete? Do you see the day when we no longer have to use hooks and instead signals become the bedrock of everything in React? Let me know what your thoughts are in the comment section. If you'd like to learn more about React and React hooks then you can check out my YouTube channel where I have a React course for Javascript Developers with over 15 videos on introduction to React, this course is designed to teach you how to build Godlike modern frontend applications with React.
Top comments (36)
We've had signals-like implementations in state management libs for react for quite some time, however these aren't real signals. The concept of signals was made popular by solidjs (signals is the backbone of solidjs) and got a lot of attention when angular adopted the same pattern. React cannot do real signals, because it needs to always traverse the entire component tree, which goes against the principles of signals. Signals implementations in React are just a facade that visually make it look like signals, but if you look at the source, you will see that they use some form of observer lib like rxjs to subscribe to state updates and then normal react useState hook, which will trigger a traversal of the entire component tree in the vdom.
Yes I agree with the part where you said they used RXJS under the hood. When I first checked signals out the first thing that came to my mind is no way React is doing this thing by default. Something else is happening under the hood.
I didn't know about signal like implementation in other state management libraries.
I'm pretty sure signals were already popular on linux development before solidJS came to exist
Hah, well we'll have to ask Ryan where he got the idea then :p
Official by whom? Can you please share a link to React (not Preact) documentation? I didn't even see a mention of signals in the official documentation.
If this article about Preact why I see React in the title and keywords?
Are you sure you took your time to read through the whole article?
I did read it, and also didn't find any confirmation of this bold claim. Only a link to your YouTube channel.
Oh I see where the confusion is, well I actually attended the funeral where we laid Hooks to rest.
Anyway if you did read the full article then you'd see where I stated "Personally in my humble opinion signals will replace some hooks but not all hooks".
The goal of this post at the end the day is not to prove that React hooks are dead rather it is to introduce the concept of signals in a friendly way.
I know you don't want them to take hooks away yes we all love using hooks but if there's something that gets the job done more easier than hooks I don't know about you but I'll definitely go for it.
There is no confusion, you just use a false claim, and thatβs it.
To clear confusion I think @usulpro is referring to your use of "official" included in your claims with no "official" announcement anywhere. I've read the entire article and it changed nothing.
Signals is the reason I started using SolidJS instead of React. The only downside was not being able to take advantage of the huge React ecosystem. I will have to give these a try. Thanks for the article.
You're welcome. Now React has it's own implementation of signals hopefully you can start using React.
Hey @kalashin1, do you mean Preact?
No, I meant for React. However the signal Library was built by Preact.
Can you link the documentation here?
Here's the link to the documentation
React and Preact are different libraries man!
Please make it clear that "React doesn't have it's own implementation of signals yet"
Interesting and I'm not against the idea of signals but I honestly can't see the advantage of signals over hooks at this point. Feels like we're (once again) reinventing the wheel.
Also you basically get this out-of-the-box with Vue, the entire render engine is based around this sort of concept.
We are always moving back and forth in the world web app development.
I hate to be that guy, but if React hooks were dead why do approximately 99% of React apps (past, present, and foreseeable future) still use them?
Because it's what developers are used to and hey hooks still help us get the job done.
So... they're not dead? π
not totally π
Hold on... are you trying to say that React will finally be... reactive? It only took 10 years for the name not to be ironic
π everything isn't the way it always seem.
Hey @kalashin1 really nice post.
Can you create a similar for Angular as well? We've got signals over there as well. π
It's been really long since I used Angular but hey I'm going to try my best.
fdsfds
How can i update the signal , is it just a like updating the object value using the key ?
totally.
Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more