Introduction
State management is an essential aspect of building complex applications. Recoil is a state management library developed by Facebook, which provides a simple and efficient way to manage states in React applications & better component rendering cycles. In this blog post, we will explore the basics of Recoil and how it can help you build more scalable and maintainable applications.
What is Recoil?
Recoil lets us create a data-flow graph that flows from atoms (shared state) through selectors (pure functions) and down into the React components. Atoms are units of the state that components can subscribe to. Selectors transform this state either synchronously or asynchronously. To further simplify development experience, Recoil provides several convenient hooks such as useAsyncQuery, useQueryWithParams, useLoadingIndicator.
Recoil is composed of ATOMS and SELECTOR
1. Atoms: Atoms are units of the 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 as well. 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. Now the above atom can be used by multiple components just like a normal useState variable & also can be changed-updated.
2. Selectors: A selector is a pure function that accepts atoms or other selectors as input. 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.
Selectors are used to calculate derived data that is based on state. This lets us avoid redundant state, usually obviating the need for reducers to keep state in sync and valid. Since selectors keep track of what components need them and what state they depend on, they make this functional approach more efficient.
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.
Here, userNameFormatState
has one dependency: the userNamState
atom. Conceptually, the userNameFormatState
selector behaves like a pure function that takes a userNameState
as input and returns a formatted font size label as output.
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 userNameFormatState
selector is not writeable.
Asynchronous Data Queries
Recoil provides a way to map state and derived state to React components via data flow graph. What’s really powerful is that the functions in the graph can also be asynchronous. This makes it easy to use asynchronous functions in synchronous React component render functions. Recoil allows seemlessly mix synchronous and asynchronous functions in the data flow graph of selectors. Simply return a Promise to a value instead of the value itself from a selector get
callback, the interface remains exactly the same. Because these are just selectors, other selectors can also depend on them to further transform the data.
Queries with Parameters
Sometimes if we want to be able to query based on parameters that aren’t just based on derived state. For example, you may want to query based on the component props. You can do that using the selectorFamily
helper:
Displaying Loading Indicator While Fetching Data:
useLoadingIndicator
hook simplifies the process of displaying loading indicators during data fetching, enhancing the user experience and providing visual feedback.
In conclusion, comparing it with other state management libraries (like Redux), recoil seems more “React-like” and simpler & easier to learn.
Thanks :)