How to use Recoil State Management Tool in React

And finally, the creators of Facebook have come up with a state management tool to replace the redux. Here in this article, we will discuss the steps to use the Recoil state management tool in a React app.

Prerequisites

To follow this article, the reader should be aware of the following technologies:-

  • JavaScript ES6
  • React.js library
  • State-management tools in React

What we will learn

In this article, we will learn the following things:-

  • Basic terms to know before start working with Recoil
  • Why Recoil over Context API and Redux
  • To Create a React project
  • Creating components in a React app
  • Integrating Recoil in our app
  • Structuring a React Recoil project

After completing this article, we will create a demo app using React and Recoil that accepts a name and displays its length.

Basic terms to know before start working with Recoil

If you want to learn about Recoil in deep, refer to the official website of Recoil state-management tool. Under this heading, I am explaining the basic terms we need to know when working with React and Recoil.

1. Atoms

In the official documentation, we could see that atoms are units of the state. But in a simple way, we can figure out an atom is a global state. It can be subscribed to and updated from any component.

If a component is subscribed to an atom, any change in the atom will re-render the component.

An atom consists of two fields.

  • key – A unique key (with respect to other atoms/selectors)
  • default – A default value

In the code below, we can see an example atom ageState with key ageState and default value 27.

const ageState = atom({
  key: 'ageState',
  default: 27,
});

This atom can be accessed and can change its value from any component in our app.

Here the useRecoilState hook by recoil works the same as the useState hook in React. The difference is that the useRecoilState is dealing with atoms instead of local states.

import { useRecoilState } from "recoil";

function AgeInputComponent() {
  const [age, setAge] = useRecoilState(ageState);
 return (
    <input
      type="text"
      placeholder="Enter the age"
      onChange={()=>setAge(e.target.value)}
      value={age}
    />
  );
}

Another recoil hook useRecoilValue can be used to access the atom value from any other component. Note that, it can not update the atom value.

import { useRecoilValue } from "recoil";

export default function AgeDisplayComponent() {
  const age = useRecoilValue(ageState);

  return <h3>{age}</h3>;
}

2. Selectors

Selectors are pure functions that accept atoms or any other selectors as it’s input. It will return a result corresponding to the change in input.

Below, we can see a selector agePlusOneState that accepts the ageState we created and returns the age+1 value.

import { selector } from "recoil";

export const agePlusOneState = selector({
  key: "agePlusOneState", // unique ID (with respect to other atoms/selectors)
  get: ({ get }) => {
    const age = get(ageState);
    const agePlusOne = age+1;
    return agePlusOne;
  },
});

The get property is the function that is to be computed. It can access the value of atoms and other selectors using the get argument passed to it.

Why Recoil over Context API and Redux?

React already have a built-in feature Context API that enables initializing global states in a React app. Other than passing states from one component to another as props, we can store states in global storage and can be accessed from any of the components.

Redux is a well-established library that can completely manage the states in a React application. Before Context API, Redux was the only way to implement global states. It can be defined as the React boilerplate with state management. But the main drawback of the Redux library is that it needs a lot of time to set up and implement functions.

Also in Redux, it has to ask each connected component whether it needs to re-render.

Now, when coming to Recoil, it is backed up by Facebook, which is the same team behind the React library. It is minimal. Other than Redux, when we edit the data in an atom, the only components subscribed to that atom will re-render.

Use Recoil State Management Tool in React

Now let us come to our topic. We will create a React app and use the Recoil state management tool in it. Here we will code two components, an input box, and a component to display the length of characters typing inside the input box.

Note that, we only need a state management tool for medium or large-scale applications. If we are planning to build small tools, passing the states and functions as props are recommended.

Refer to the file structure of the app before continuing the article. Because we are not explaining the position of files/components going to create.

Create a new React project

The first step is setting up a React application on your system. This can be easily done using the NPX tool.

So, install Node.js on your system first and create a react application using NPX. Don’t bother about the term NPX, because it’s a tool coming with NPM(Node Package Manager) 5.2+ onwards which will install on your system with Node.js itself.

If you need further assistance in the installation of React on your system, use the below links.

Install React on WindowsUbuntu, and macOS

npx create-react-app react-recoil-demo-app

This command will create a react application with the project name react-react-recoil-demo-app

Now enter the project directory and start the app.

cd react-recoil-demo-app
npm start

It will open up the React application we have created in our browser window with the address https://localhost:3000. The port may vary if 3000 is busy.

Now we can use our favorite code editor to edit our project. I personally recommend Visual Studio Code.

Install the Recoil package

We can simply install the Recoil package using NPM. Execute the below command in the terminal.

npm install recoil

Wrap the entire app inside RecoilRoot

To start using the Recoil state management tool inside our React app, we need to wrap the entire app inside a RecoilRoot component. If you are already familiar with Redux or Context API, this step will be common.

So inside our App.js component, we will import a component Main that contains all other components. This Main component is wrapped inside the RecoilRoot component.

// src/App.js

import React from "react";
import { RecoilRoot } from "recoil";
import Main from "./components/Main";
import "./style.css";

function App() {
  return (
    <RecoilRoot>
      <Main />
    </RecoilRoot>
  );
}

export default App;

Declare the Atom

We need to create a directory named atoms to store all our atoms. We can simply define an atom as a global state.

Now for our app, let us create an atom file name.js inside the atoms directory. This atom is used to store the name that we type inside the input component.

// src/atoms/name.js

import { atom } from "recoil";

export const nameState = atom({
  key: "nameState", // unique ID (with respect to other atoms/selectors)
  default: "", // default value (aka initial value)
});

Declare the Selector

Selectors are simply the pure functions that accept atoms, execute any logical operations, and return a result.

Here in our app, we are defining a selector lengthState that accepts our atom nameState, finds its length, and returns it.

// src/selectors/name.js

import { selector } from "recoil";
import { nameState } from "../atoms/name";

export const lengthState = selector({
  key: "lengthState", // unique ID (with respect to other atoms/selectors)
  get: ({ get }) => {
    const name = get(nameState);
    const lengthOfName = name.length;
    return lengthOfName;
  },
});

The Main component

Now let us code the Main component that we already imported in the App.js file. It consists of two components as below.

  • InputComponent – That handles the input field and store the input value in the recoil state as nameState atom.
  • LengthComponent – The fetches the result from lengthState selector and diplay it.
// src/components/Main.js

import React from "react";
import InputComponent from "./InputComponent";
import LengthComponent from "./LengthComponent";

export default function Main() {
  return (
    <div className="main">
      <InputComponent />
      <LengthComponent />
    </div>
  );
}

Create an Input component

In this component, we are creating an input box that accepts any string. We are storing this string in a recoil state as an atom (global state).

In React, we have a hook called useState to declare state variables inside a component. In the same manner, we have useRecoilState to declare global state variables in our app.

We already initialized the value of this state when defining the atom.

// src/components/InputComponent.js

import React from "react";
import { useRecoilState } from "recoil";
import { nameState } from "../atoms/name";

export default function InputComponent() {
  const [name, setName] = useRecoilState(nameState);

  let handleChangeInput = (e) => {
    setName(e.target.value);
  };

  return (
    <input
      type="text"
      placeholder="Enter the string"
      onChange={handleChangeInput}
      value={name}
    />
  );
}

Create the Length component

We have a hook by Recoil useRecoilValue, that that enables the feature to use the atom values and subscribe to it. Subscribing to the state will re-render the component with any change in the atom.

// src/component/LengthComponent.js

import React from "react";
import { useRecoilValue } from "recoil";
import { lengthState } from "../selectors/name";

export default function LengthComponent() {
  const length = useRecoilValue(lengthState);

  return <h3 className="length">{length}</h3>;
}

Add some styles to our app

Add some styles to make our app a bit shinier. We are creating a file style.css inside the src directory and this file will be imported into our App.js file. We already imported it in the first step.

// src/style.css

.main {
  text-align: center;
  margin-top: 10rem;
}
input {
  height: 2rem;
  width: 20rem;
  border: 1px solid #c9c9c9;
  font-size: 1.2em;
  padding: 0.3rem;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}
.length {
  font-size: 3.5em;
}

Codesandbox

Refer to the CodeSandbox link to view the live app. You can clone this project to your CodeSandbox account and edit the code also.

https://codesandbox.io/s/trusting-aryabhata-cy4jx

GitHub

You can always refer to the GitHub repository to clone this project, refer to the code and work on top of it.

https://github.com/techomoro/react-recoil-demo-app

Summary

So in this article, we discussed the steps to use the Recoil state management tool in a React app. Here, we are using the best folder and file structure. Codesandbox and GithubRepository links are also added in this article.

Be the first to reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.