Biggest Challenge in React application is the management of global state. In large applications, React alone is not sufficient to handle the state complexity which is why some developers use React hooks, Redux and others state management libraries.
Do You Need A State Management Library?
For reasons of compatibility and simplicity, it's best to use React's built-in state management capabilities rather than external global state like Recoil. But as i said before React has certain limitations when it comes to a global state management.
Component state can only be shared by pushing it up to the common ancestor, but this might include a huge tree that then needs to re-render.
Context can only store a single value, not an indefinite set of values each with its own consumers.
Both of these make it difficult to code-split the top of the tree (where the state has to live) from the leaves of the tree (where the state is used).
So When Should We Use A State Management Library Like Recoil?
Applying a global state management is not so easy, it is a lot off hard work and it also takes time to implement. So, it is very important for you to know when to implement the state-management.
- If your application contains a large number of components and a lot of requests are being sent to the back-end for data retrieval, then it becomes mandatory to implement the state-management, as it will boost the user experience and speed of the application to a great extent. With a global state, you don't have to fetch the same request multiple times as the data will already be "cached" from the first request and can be consumed by other part of your screen.
- If you use redundant data throughout the whole app, for example, a list of customers is being used in the invoice creation and sales report generation then there is no need to fetch customers again and again from the database. You could simply just put the data in the global state.
What is it about Recoil.js that’s so appealing?
Recoil feels just like React. The syntax is similar to React and it looks like a part of React API. Other than that, it has many other upsides like it solves the problem of global state management, shared state, derived data, etc. The team at Recoil make sure that the semantics and behavior of Recoil be as Reactish as possible.
The Recoil Concept.
Recoil is an experimental state management library at Facebook, created by Dave McCabe. The reason why i like Recoil better than Redux is because Recoil solves all our complex state management problems but its configuration is surprisingly simple, unlike Redux. And we do not need to write much boilerplate code as we would have by using other state management library like Redux.
Installing Recoil
As Recoil is a state management library for React, you need to make sure that you have React or React Native installed and running before getting started.
npm install recoil
// or
yarn add recoil
Core Concept of Recoil
There are two core concepts of Recoil that you need to understand. This are Atoms and Selectors.
Atoms
Atoms are units of state. They're updateable and subscribable: when an atom is updated, each subscribed component is re-rendered with the new value. They can be created at runtime, too. Atoms can be used in place of React local component state. If the same atom is used from multiple components, all those components share their state.
You can create Atoms with the atom
function:
const countState = atom({
key: 'countState',
default: 1,
});
Atoms use a unique key for debugging, persistence, and mapping of all atoms. You can't have a duplicate key among the atoms. So because of that you need to make sure they're globally unique. And also like a React component state, they also have a default value.
To read and write an atom from a component, we use a hook called useRecoilState
. It's just like React's useState
, but now the state can be shared between components:
function CountButton() {
const [countValue, setCountValue] = useRecoilState(countState);
return (
<>
<h4>Count Value {countValue}</h4>
<button onClick={() => setCountValue((value) => value + 1)}>
Click to Increase Count
</button>
</>
);
}
Selectors
A selector is basically a piece of derived state, where ‘derived state’ can be defined as the ‘the output of passing state to a pure function that modifies the given state in some way’. So in short when these upstream atoms or selectors are updated, the selector function will be re-evaluated. Components can subscribe to selectors just like atoms, and will then be re-rendered when the selectors change.
const countLabelOddEventState = selector({
key: 'countLabelOddEventState',
get: ({get}) => {
const count = get(countState);
if (count % 2 == 0) {
return `isEven`;
}
return `isOdd`;
},
});
As you can see Selectors also have a unique ID like atoms but not a default value. A selector takes atoms or other selectors as input and when these inputs are updated, the selector function gets re-evaluated.
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. Whenever it accesses another atom or selector, a dependency relationship is created such that updating the other atom or selector will cause this one to be recomputed.
Selectors can be read using useRecoilValue()
, which takes an atom or selector as an argument and returns the corresponding value. We don't use the useRecoilState()
as the countLabelOddEventState
selector is not writeable (see the selector API reference for more information on writeable selectors).
Conclusion
Personally i think Recoil is a great library but unless you have some specific problems regarding global state management, you don’t really need it. It's nothing that the developer’s world couldn’t survive without. You can even use Recoil partially in your application, exactly where you need, without having to adopt it for the entire application.
Top comments (0)