React Recoil for State Management
Overview
Just like Redux, React Recoil is another state management library, developed by Facebook for creating React applications. React Recoil provides a global state so that all the react components can share the states easily. There are two core concepts involved while using React Recoil : Atoms and Selectors. React Recoil provides a useRecoilValue hook that takes in an atom or the selector as an argument and returns the value of the given Recoil state.
What is Recoil?
There are various state management libraries available in React and out of all, Redux is the most powerful and preferred choice of developers. Just like Redux, React Recoil is another state management library for creating React applications. React Recoil is an open-source library, developed by Facebook which is very easy to set up. Unlike Redux, we don't need any boilerplate code to get started with React Recoil.
Note that Recoil React is still in the experimental phase and has not been released in a stable version yet but it might prove to be the best choice for React developers in near future.
Recoil React provides a global state so that all the react components can share the states easily. Recoil React also helps us to avoid unnecessary re-renders which occur while using Redux or the Context API.
There are two core concepts involved in implementing Recoil React :
- Atoms and
- Selectors.
1. Atoms
Atoms are the units of the global state provided by Recoil React, which can be subscribed by the react components individually.
We know while using Context API, when the state in the context changes, all the components get re-rendered even if in some of the components, the data is not changed. To eliminate such unnecessary re-renders, React Recoil uses atoms.
When an atom is changed or updated, only the react components which are subscribed to the atom, are re-rendered with the updated value.
The atom function takes in an object as a parameter where the object contains a key (unique key value) and a default value. The atom function can be exported with an atom name so that it can be read from other components as well.
Just like the useState hook, we have the useRecoilState hook which can be shared between the react components and often used to read an atom from a component.
Example :
In the below example code, we have used the useRecoilState hook and passed in the Atom_state_name atom as a parameter. It will return an array consisting of the name as the default value of the atom and the setName() function for updating the default value of the atom.
Whenever we change the value of the input box, the updated value in the solvent component is shared with the other components as well, which are subscribed to the Atom_state_name atom.
Note : that all the subscribed components will be re-rendered with the updated value.
2. Selectors
A selector is a function that takes in an object as a parameter where the object contains a key (unique value) and a getter function. get() function helps perform logical stuff wherein the computed value can be returned and accessed by the components.
Just like atoms are subscribed by the components, selectors can also subscribe to the atoms, and further, components can subscribe to the selectors. Whenever an atom is updated/changed that is subscribed by the selector, the selector() function is evaluated again. Also, the components subscribed to the selector will be re-rendered when the selector gets updated.
Using selectors, we can manipulate the states either synchronously or asynchronously.
Example :
Note that in the below example code, we have used the useRecoilValue hook which is one of the important hooks while using React Recoil. useRecoilValue hook takes in an atom or the selector as an argument and returns the value of the given Recoil state.
- If the value of the state has to be accessed directly within the component, then we pass the atom inside the useRecoilValue hook.
- We pass the selector to the useRecoilValue hook when computation is required or logical operations need to be performed on the value of the atom state.
What is the Need to Use React Recoil?
Now the biggest question arises if we have so many state management libraries including Redux, and context API, then why should we use Recoil React for creating React applications?
Let us highlight some more features of React Recoil below :
- Recoil React provides a global state that can be used by the react components easily using atoms and selectors. There is no concept of prop drilling involved while working with Recoil React, in which we have to pass the states as props to the children's components so that they can use the state.
- We don't need any boilerplate code to get started with Recoil React, unlike Redux.
- Once the react components are subscribed to the atoms and the selectors, they will be re-rendered with the updated/changed state values whenever there is a change in an atom or the selector state. In this way, we can avoid unnecessary re-renders even if in some of the components, the data is not changed.
How to Use React Recoil for State Management?
In this section, we will look at how to set up and use Recoil React. We will understand this in detail with the help of an example for creating a simple classic to-do application in React.
Installing React Recoil
Before using Recoil React, we must know how to install it and set it up on our local computer system. We can simply install React Recoil either using npm or yarn as shown below.
Adding Root Component of React Recoil
As we know that Recoil React uses a hook-based approach, so it's always preferred and recommended to wrap the entire application code with the root component provided by Recoil React. In this way, we can access the application state from any component easily.
We have to import and add the RecoilRoot component in the index.js file of React.
Note that in the below code, we have wrapped the application App component inside the RecoilRoot component.
Creating Atom in React Recoil
As we have learned till now that the atoms are the units of the global state provided by React Recoil, which can be subscribed by the react components individually. When an atom is changed or updated, only the react components which are subscribed to the atom, are re-rendered with the updated value.
Note that we can create as many atoms as we want. For creating an atom for a to-do React application, we can create a new file named todo_atom.js at location : src/recoil/atom/todo_atom.js and add the following code :
Here, the key denotes the unique key value and the default denotes the default value of the atom i.e, an empty array here.
Adding Data to an Atom
We have now created another component file at location : components/todo_item_create.js. In this component, users can type their to-do tasks in the input box and can simply add them by clicking the Click to add task button.
After clicking the button, the add_item() function will be called which further calls the setList() function returned by the useRecoilState hook. Note that by using the setList() function, we are changing/updating the atom state of React Recoil. It is highly recommended to create a shallow copy (...old_List) of the previous data before adding a new object (to-do task here).
As soon as the atom gets updated, the react component subscribed to the Atom_todo_list atom will get re-rendered and the newly added to-do task will be displayed along with previously stored tasks.
Consuming Data from the Atom
We now have to display a to-do tasks list on screen and also, enable users to manipulate those tasks (update, delete, or tick-mark as done). For that, we have created another component file named todo_main.js at location : src/components/todo_main.js.
We have used the useRecoilValue hook which returns the current state i.e, an array of data present in the atom. Using the hook, we will get the list of all the to-do tasks and then, we can use the JavaScript map() function to loop over the tasks and display them on the screen.
Updating Data in the Atom
In the below code, we have added another component for manipulating the to-do tasks. Users can modify, delete, and toggle checkboxes (whether done or not) for all the listed to-do tasks. We have used the useRecoilState hook which returns the current atom object data in form of a list.
On modifying the to-do task, the editText() function will be called where we will replace the text key of the atom with the event.target.value (updated text). setList() function updates the content of the atom and hence, all the subscribed components get re-rendered.
On toggling the checkbox for a to-do task, the checkItem() function will be called where we will toggle the value (false -> true and true -> false) of the pending key of the atom. setList() will again set the updated content in the atom.
On clicking the Delete button, the delete() function will be called wherein we will delete the specified task from the atom list. Again setList() function will re-render the subscribed components and we won't see the deleted task thereafter.
Note that replaceAtIndex() and removeAtIndex() are helper functions that are used in the code to replace or remove the content of the array at the specified index.
React Recoil as a Replacement for React Redux
React Developers can easily relate to it that for a very long time, React Redux is the only reliable and the most widely used state-management library for creating React applications.
But for React Developers, the overall developer experience was not so good while working with React Redux. In previous versions of React Redux, we had to manually set up the global data store, manually connect each component and manually update the global state. It was very time-consuming and used to take a lot of effort from the React developers. There is a lot of code involved in React Redux but over time, it has improved significantly. It now provides easy plug-in solutions like react redux-toolkit etc.
As we have learned till now, we also have Recoil React which is another state management library (currently in the experimental phase). Recoil React is simple and beginner-friendly and doesn't require any boilerplate code to get started. Unlike Redux, Recoil React is easy to set up, even easier than react redux-toolkit (plug-in solution of React Redux).
Note that Recoil React has not been released in a stable version yet but it might prove to be the best choice for React developers for creating react applications shortly.
Conclusion
- Just like Redux, Recoil React is another state management library for creating React applications, developed by Facebook.
- Recoil React is easy to set up and unlike Redux, we don’t need any boilerplate code to get started.
- Recoil React provides a global state so that all the react components can share the states easily.
- There are two core concepts involved in implementing Recoil React :
- Atoms
- Selectors
- Atoms are the units of the global state provided by Recoil, which can be subscribed by the react components individually.
- When an atom is changed or updated, only the react components which are subscribed to the atom, are re-rendered with the updated value.
- Whenever an atom is updated/changed that is subscribed by the selector, the selector() function is evaluated again. Also, the components subscribed to the selector will be re-rendered when the selector gets updated.
- useRecoilValue hook is one of the important React Recoil hooks that takes in an atom or the selector as an argument and returns the value of the given Recoil state.
- If the value of the state has to be accessed directly within the component, then we pass the atom inside the useRecoilValue hook.
- We pass the selector to the useRecoilValue hook when computation is required or logical operations need to be performed on the value of the atom state.
- Recoil React is still in the experimental phase and has not been released in a stable version yet but it might prove to be the best choice for React developers in near future.