Overview
Recoil is a state management library for React. It has some good points as below :
- Minimal and Reactish: Recoil works and thinks like React. Add some to your app and get fast and flexible shared state.
- Data-Flow Graph: Derived data and asynchronous queries are tamed with pure functions and efficient subscriptions.
- Cross-App Observation: Implement persistence, routing, time-travel debugging, or undo by observing all state changes across your app, without impairing code-splitting.
Structures
There are 2 main components of Recoil
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.
const fontSizeState = atom({
key: 'fontSizeState',
default: 14,
});
Selector
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.
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
get: ({ get }) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});
Setup Nextjs with Recoil
1. Install recoil
yarn add recoil
2. Add RecoilRoot
Components that use recoil state need RecoilRoot to appear somewhere in the parent tree. A good place to put this is in your root component:
_app.js
import { RecoilRoot } from 'recoil';
export default function MyApp({ Component, pageProps }) {
return (
<RecoilRoot>
<Component {...pageProps} />
</RecoilRoot>
);
}
3. Define recoil atom and selector
lib/recoil-atoms.js
import { atom, selector } from 'recoil';
export const categoryState = atom({
key: 'category',
default: '',
});
export const setCategory = selector({
key: 'setCategory',
set: ({ set }, category) => {
set(categoryState, category);
},
});
4. Put all together
index.js
import React, { useState } from 'react';
import { categoryState, setCategory } from '../lib/recoil-atoms';
import { useRecoilValue, useSetRecoilState } from 'recoil';
const IndexPage = () => {
const [inputValue, setInputValue] = useState('');
const category = useRecoilValue(categoryState);
const changeCategory = useSetRecoilState(setCategory);
function handleChange(e) {
setInputValue(e.target.value);
}
function handleSubmit(e) {
e.preventDefault();
const getValue = inputValue.trim();
// check if value exists
if (getValue) {
changeCategory(getValue);
// reset input value
setInputValue('');
}
}
return (
<>
<h1>Category: {category}</h1>
<form onSubmit={handleSubmit}>
<input value={inputValue} onChange={handleChange} />
<input type="submit" value="Change Category" />
</form>
</>
);
};
export default IndexPage;
Conclusion
Recoil is lightweight and easy to use, there are even more advance features.
Visit Recoiljs for more information.