State Management in React with Recoil
State management is a big part of our modern web applications. The need for a global state manager was felt since the beginning of React.
Then Redux came into the picture and won it. It has become the go-to state management solution for most large-scale applications.
But redux is far from perfect. And recently it seems that the popularity of redux is declining. Many new players have joined the game of state management and Recoil is one of them.
So what’s Recoil anyway?
Simply speaking Recoil is yet another state management solution for React. React community has jumped up after the introduction of RecoilJS. It has been gaining popularity at a very fast pace.
It is maintained by a team at Facebook (who are also the maintainer of React).
Although keep in mind that Recoil is not the official state management library for React.
Why should you care?
Recoil has some distinct benefits over other state management libraries
It has fewer boilerplate (as opposed to redux)
Easy to learn and understand (opposite to redux)
Easy to understand the data flow (opposite to redux)
More in line with modern React (support concurrent mode)
Excellent developer experience
Performance is not an issue
Lot’s of promises here. But is this library really that good? Let’s glance over the library itself to find out the answer!
Main Concepts of Recoil
Any State management library has 3 purposes mainly
Creating the state
Reading data from state
Updating the state
1. Creating the State
You can use 2 things to create a store in Recoil.
Atom
Selector
Let’s see how to use them.
1a. Atom
According to documentation
Atoms contain the source of truth for our application state
In simple terms, atoms are a piece of data that you want to store in the state. it can be the theme of your application or a list of todo.
const todoListState = atom({
key: 'todoListState',
default: [],
});
If you want some piece of your data to be stored and accessed globally you have to create an atom for that.
1b. Selector
According to do documentation
A selector represents a piece of derived state
That means if
You want to derive some data from other states
Or want to compute something based on the data stored in atoms
You can use selectors for this purpose. For example, you saved your todos in the todoListState
atom. Now you want to filter the todoList
based on their status. You can use a selector for that.
const filteredTodoListState = selector({
key: 'filteredTodoListState',
get: ({get}) => {
const filter = get(todoListFilterState);
const list = get(todoListState);
switch (filter) {
case 'Show Completed':
return list.filter((item) => item.isComplete);
case 'Show Uncompleted':
return list.filter((item) => !item.isComplete);
default:
return list;
}
},
});
2. Read the Values
Recoil has provided us with some nice hooks. One of them is useRecoilValue
which can be used to read the data from the atom or selector.
function TodoList() {
const todoList = useRecoilValue(filteredTodoListState);
return (
<>
{// render something based on todoList value}
</>
);
}
3. Update the values
One nice thing about Recoil is that it’s more Reactish.
We have useState
hook in React. Recoil has provided us with a similar hook named useRecoilState
. It can be used to set the state of the atom or selector.
function TodoList() {
const [todos , setTodos] = useRecoilState(todoListState);
useEffect(() => {
setTodos() // -> set the initial list of todos here
}, [])
return (
<>
{// render something based on todoList value}
</>
);
}
There are some other utilities that can help you in different scenarios. You can take a look at the documentation
Will it replace Redux?
The short answer is… NO! Let me explain
Recoil is not the solution for everything
Recoil is designed to solve a very specific problem. If you have lots and lots of inter-dependent components then it can help you to boost performance.
On the other hand, redux is more generic. It's not even specific to React.
Recoil is large in size
If you go to the NPM you can see the size of these packages.
recoil = 1.56 MB redux+ react-redux = 448 Kb
So Recoil is significantly larger than the Redux. In many cases especially where bundle size is important this becomes an important issue.
Recoil is not ready… yet
Recoil is fairly new compared to redux. It’s being actively developed. But you can expect many unexpected hiccups along the way! It’s not considered production-ready yet.
But Redux is an established library with lots of other libraries to support it. Also, it’s more stable and has excellent support from the community.
Redux is getting better
Most of the issues are with the verbosity of Redux. The introduction of the redux toolkit has solved this problem too (Almost :p ).
And with strong community support and active development, it will get better day by day.
Many large projects already use Redux
Redux is not going anywhere. At least not for the next 2–3 years. Many large projects are already being run using redux and it’s hard to change the architecture overnight.
So if you are targeting for a job more often than not Redux will be more desirable on your resume!
Recoil does not have middleware support
Currently, Recoil does not support middlewares. Maybe it will come in the future. But I think you should consider this before adopting.
So should you learn Recoil?
Absolutely yes!
It has introduced some new interesting concepts. Maybe try this out for some fun little project. Play with it. Know when this can be useful. If your project requires it then use it.
Most importantly, keep learning! Have a great day!
Have something to say? Get in touch with me via LinkedIn