Recoil is the Samurai Sword of React State Management
Tags: react, nextjs, redux, javascript
Published: 2023-02-27 05:29:01

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](https://github.com/facebookexperimental/Recoil/issues/1495) 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](https://recoiljs.org) was created to provide an alternative to [Redux](https://redux.js.org) 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
```

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:

```react
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>
);
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dliz9y75ktrao9ofpkyd.png)

---

## **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.._

```react
import { atom } from 'recoil';

export const weaponState = atom({
  key: 'weaponState',
  default: {
    name: 'Katana',
    damage: 50,
  },
});
```

#### **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.._

```react
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>
  );
}
```

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.._

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

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

#### **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.._

```react
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>
  );
}
```

#### **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.

```react
import { atomFamily } from 'recoil';

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

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.

```react
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>
  );
}
```

---

## **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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aw11i8mp03j3lsawycky.png)

---

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.._

```react
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>
  );
}
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5qomoot8hv5wde4jqhz1.gif)

---

## **🍀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](https://youtube.com/@codeofrelevancy)
[Discord](https://discord.com/invite/f8jwnzcRz2)
[GitHub](https://github.com/codeofrelevancy)

![Thank you in advance for your support](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pupi7vabildbmp7g2d7j.gif)