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
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>
);
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.
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,
},
});
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>
);
}
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;
},
});
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>
);
}
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,
}),
});
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>
);
}
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
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>
);
}
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
🍀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!