DEV Community

Cover image for Recoil is the Samurai Sword of React State Management
Code of Relevancy
Code of Relevancy

Posted on • Edited on

Recoil is the Samurai Sword of React State Management

Today, I have taken a new approach to present this article by adding a Samurai touch. I sincerely hope that it adds value to your reading experience. Your feedback is always welcome and appreciated so please share your thoughts in the comments section below..


🚨Important Notice

Recoil is currently experiencing a lack of updates and maintainer support which has caused concern among developers in the community. On other side many developers have enjoyed using Recoil and found it to be a helpful state management library. So we recommend exercising caution when deciding whether to continue using it in new projects.

The most recent update to Recoil was made on Oct 12, 2022. This lack of updates has caused some developers to switch to other state management libraries and may indicate that Recoil is no longer a reliable choice for future projects. The lack of maintainer support may mean that issues and bugs are not addressed in a timely manner which could cause problems for your app.

In case you choose to continue using Recoil we recommend keeping an eye on its development and considering alternative options as well. It's always important to make informed decisions when selecting tools for your project and we want to ensure that our readers are aware of the current state of Recoil before making a decision.

Please note that this message was last updated on March 9, 2023 and the situation with Recoil may have changed since then.

Happy coding..


Recoil was created to provide an alternative to Redux which is another popular state management library for React. In today's adventure, we will see what Recoil is, how it works, why you might want to use it in your React apps and much more..

With a spirit of the samurai, let's begin our adventure..


Installing Recoil - The Way of the Samurai

You can install Recoil using npm or yarn by running the following command in your terminal:

npm install recoil
Enter fullscreen mode Exit fullscreen mode

Components that use recoil state need RecoilRoot to appear somewhere in the parent tree. A good place to put this is in your root component:

import React from "react";
import ReactDOM from "react-dom/client";
import { RecoilRoot } from "recoil";
import App from "./App";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  <React.StrictMode>
    <RecoilRoot>
      <App />
    </RecoilRoot>
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

This ensures that the state is available to all child components that require it and avoids any potential issues with components not being able to access the state due to missing RecoilRoot components. In the way of the samurai, there is no room for error. So proceed with vigilance and honor.


What is Recoil?

Recoil is a state management library for React that was released by Facebook in 2020. It provides a simple and intuitive way to manage the state of a React application. Recoil is built on top of React's Context API which is used to pass data down the component tree. Anyway, Recoil provides a more powerful and flexible way to manage the state of an application than the Context API.

The core idea behind Recoil is that state should be defined as a collection of atoms. An atom is a piece of state that can be read and updated by components. Components can subscribe to atoms to be notified when their value changes.

Recoil also has a secret weapon - The Selectors, powerful functions that derive new state from atoms or other selectors. Selectors can be used to compute derived data from the state of an application.

samurai's sword


How does Recoil work?

The art of Recoil is rooted in the samurai's keen understanding of the world around them. It works by defining a collection of atoms and selectors that represent the state of an application. Atoms are defined using the atom() function, it takes an initial value as a parameter. Selectors are defined using the selector() function which takes a function that computes the derived state as a parameter. Together, atoms and selectors form the backbone of Recoil.

Create an atom

In the way of the Samurai, an atom in Recoil is like a sword. It's an unit of state that can be read and written to by different parts of your app. To create an atom you can use the atom function from the Recoil library.

To show you what I mean..

import { atom } from 'recoil';

export const weaponState = atom({
  key: 'weaponState',
  default: {
    name: 'Katana',
    damage: 50,
  },
});
Enter fullscreen mode Exit fullscreen mode

Use the atom in a component

Components can subscribe to atoms and selectors.
To use the weaponState atom in a component you can use the useRecoilState hook from the Recoil library.

To show you what I mean..

import React from 'react';
import { useRecoilState } from 'recoil';
import { weaponState } from './atoms';

function WeaponDisplay() {
  const [weapon, setWeapon] = useRecoilState(weaponState);

  return (
    <div>
      <h1>{weapon.name}</h1>
      <p>Damage: {weapon.damage}</p>
      <button onClick={() => setWeapon({ name: 'Nodachi', damage: 70 })}>
        Upgrade Weapon
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

As per above instance, we're using the useRecoilState hook to access the weaponState atom and its current value. We're also providing a button that allows the user to upgrade their weapon by setting the atom to a new value.

Create a selector

Selectors are functions that allow you to derive state from your Recoil atoms. They can be useful for computing complex values or aggregating data from multiple atoms.

To show you what I mean..

import { selector } from 'recoil';
import { weaponState } from './atoms';

export const weaponDamageSelector = selector({
  key: 'weaponDamageSelector',
  get: ({ get }) => {
    const weapon = get(weaponState);
    return weapon.damage;
  },
});
Enter fullscreen mode Exit fullscreen mode

Use selector in a component

We can then use selector in our components using the useRecoilValue hook same as atoms.

To show you what I mean..

import React from 'react';
import { useRecoilState } from 'recoil';
import { weaponDamageSelector } from './selectors';

function WeaponDisplay() {
  const weaponDamage = useRecoilState(weaponDamageSelector);

  return (
    <div>
      <p>Weapon damage: {weaponDamage}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Create an atomFamily

In the samurai world, a clan may have multiple samurais and each with their own unique characteristics and abilities. Similarly, in a React application, you may have multiple components that need to share state but with different identifiers or keys.

This is where atomFamily comes in handy. It allows you to create a family of atoms that share the same structure, but with different keys or identifiers. As an instance, let's say we want to create a family of atoms that represent the weapons of different samurais in a clan.

import { atomFamily } from 'recoil';

export const weaponAtomFamily = atomFamily({
  key: 'weaponAtomFamily',
  default: id => ({
    name: `Weapon - ${id}`,
    damage: 50,
  }),
});
Enter fullscreen mode Exit fullscreen mode

In above instance, id argument in the default function is the unique identifier for each atom in the family. So when we call weaponAtomFamily('Wakizashiv'), the default function will be called with 'Wakizashiv' as the id argument and will return an object representing the default weapon for that samurai.

Use atomFamily in a component

An atomFamily() takes almost the same options as a simple atom(). But the default value can also be parameterized. That means you could provide a function which takes the parameter value and returns the actual default value.

import React from 'react';
import { useRecoilState } from 'recoil';
import { weaponAtomFamily } from './atoms';

function WeaponDisplay() {
  const [weapon, setWeapon] = useRecoilState(weaponAtomFamily('Wakizashiv'));

  return (
    <div>
      <h1>{weapon.name}</h1>
      <p>Damage: {weapon.damage}</p>
      <button onClick={() => setWeapon({ name: 'Weapon - Nodachi', damage: 70 })}>
        Upgrade Weapon
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Why use Recoil?

Recoil provides several benefits over other state management libraries for React such as Redux. Let's see some reasons why you might want to use Recoil in your React projects:

Simplified state management

Recoil provides a simpler and more intuitive way to manage the state of a React app. With Recoil you can define atoms and selectors that represent the state of your app. Components can subscribe to these atoms and selectors to be notified when their value changes.

No boilerplate

Recoil also reduces the amount of boilerplate code that is required to manage the state of a React app. It allows you to define atoms and selectors with minimal boilerplate code.
On otherside, in Redux you need to define actions, action creators, reducers and store objects to manage the state of your app.

Better performance

Recoil provides better performance than other state management libraries for React. This is because Recoil uses a new algorithm called the Dependency Graph which allows it to track the dependencies between atoms and selectors more efficiently. The Dependency Graph ensures that only the components that need to be re-rendered are re-rendered when the state of an atom or selector changes which improves the performance of your app.

Familiar syntax

Recoil uses a syntax that is similar to React's built in hooks such as useState() and useEffect(). This makes Recoil easy to learn and use for developers who are already familiar with React.

Flexible and scalable

Recoil is designed to be flexible and scalable. It can be used to manage the state of small or large apps with complex state requirements. It allows you to define atoms and selectors that represent different parts of your app's state and it provides tools for managing the dependencies between these atoms and selectors.


Battle of Recoil and Redux

Image description


So my fellow samurais, let's move forward to the final chapter of our adventure together as fearless samurai warriors..


What is Atom Effects?

Atom Effects is a feature in Recoil that allows you to execute side effects when an atom's value changes. Side effects are any operations that have an impact outside of the atom's state. Such as network requests, local storage or logging.

Atom effects are attached to atoms via the effects option. Each atom can reference an array of these atom effect functions which are called in priority order when the atom is initialized.

With the help of Atom Effects, you can add subscriptions to an atom that will be triggered whenever the atom's value changes. The subscriptions can execute any side effects that are necessary for your app. The side effects can be synchronous or asynchronous.

Atom Effects can be useful in situations where you need to execute side effects based on the current state of your app. As instance, you may want to save the user's preferences to local storage whenever they make a change to a settings page.

Atom Effects are the hidden forces that shape the world around us, just as a samurai's sword is shaped by the unseen interactions of its atoms.

To show you what I mean..

import { atom, useRecoilState } from 'recoil';

export const weaponState = atom({
  key: "weaponState",
  default: {
    name: "Katana",
    damage: 50,
  },
  /* Atom Effects */
  effects: [
    ({ onSet }) => {
      onSet(weapon => {
        console.log(`The weapon has upgrade to ${weapon.name}`);
      });
    },
  ],
});

function WeaponDisplay() {
  const [weapon, setWeapon] = useRecoilState(weaponState);

  return (
    <div>
      <h1>{weapon.name}</h1>
      <button onClick={() => setWeapon({ name: 'Nodachi' })}>
        Upgrade Weapon
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The onSet callback is called whenever the value of the weaponState atom changes. In above instance, we're simply logging the new weapon of the atom to the console, but we could just as easily execute a more complex side effect.


End of adventure

Recoil is built on top of React's Context API and provides a more powerful and flexible way to manage the state of an application than the Context API. It allows you to define atoms and selectors that represent the state of your app. Components can subscribe to these atoms and selectors to be notified when their value changes. Recoil provides several benefits over other state management libraries for React such as simplified state management, no boilerplate, better performance, familiar syntax and flexibility and scalability. If you're looking for a state management library for your React projects, Recoil is definitely worth considering.

My fellow samurais, let's take up the art of Recoil and master the ways of state management.


Motivation

Motivation


🍀Support

Please consider following and supporting us by subscribing to our channel. Your support is greatly appreciated and will help us continue creating content for you to enjoy. Thank you in advance for your support!

YouTube
Discord
GitHub

Thank you in advance for your support

Top comments (13)

Collapse
 
vsosinga profile image
vsosinga

Unfortunately the development and support of Recoil seems to have stopped in the last few months, so I'm not sure I would recommend it at the moment.
For more info: github.com/facebookexperimental/Re...

Collapse
 
codeofrelevancy profile image
Code of Relevancy • Edited

Thank you for pointing it out. I will add a note about this issue in my article.

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Update:
Image description

Collapse
 
milandry profile image
Michael Landry

Great article! Would you be able to do a followup article (or a reply) regarding the following:

  • composing selectors
  • 'writable' selectors
  • comment on recoil project setup suggestions or best practices.
Collapse
 
codeofrelevancy profile image
Code of Relevancy

Sure, I will do something about this.
Thank you for your valuable feedback..

Collapse
 
stakedesigner profile image
StakeDesigner

good post

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you

Collapse
 
mrbeast profile image
Mr. Beast

The article was truly remarkable by linking recoil to a samurai culture

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you for appreciating it..

Collapse
 
msmello_ profile image
Matheus Mello

It is always good to read your posts, keep going Code. Your work is really nice.

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you boss for your kind words. I really appreciate it..

Collapse
 
lamarcke profile image
Lamarcke

Great article! The samurai in an article is a fun concept, congrats.

Collapse
 
codeofrelevancy profile image
Code of Relevancy

Thank you 🙏 boss, for appreciating my new approach of the samurai in this article.. I really appreciate it..