Mongez React Atom
Mongez React Atom (MRA) is a state management tool to manage data between Project's Components
Why?
The main purpose of the birth of this package is to work with a simple and performant state management tool to handle data among components.
Features
The top features of MRA is:
- Lightweight package: 24KB Unpacked.
- Can be used everywhere, inside or outside React Components.
- Easy to use.
- Easy to learn.
How it works
The concept is simple, everything works in atoms
, each atom SHOULD
hold a single value, in nutshell every atom has a single responsibility.
Installation
yarn add @mongez/react-atom
Or
npm i @mongez/react-atom
Usage
Let's create a new atom
src/atoms/currency-atom.ts
import { atom } from '@mongez/react-atom';
const currencyAtom = atom({
name: 'currency', // required and should be unique.
default: 'USD', // default value for the atom
});
export default currencyAtom;
Let's see what we've here,
The atom
function creates a new atom object, it accepts an object, which holds two required keys:
name
the atom's name, as mentioned earlier it must be unique for each atom, otherwise an error will be raised in the development environment.default
holds the default value, it can be any type.
Now the atom is ready to be used in our React components.
Get the atom's value
Let's update our header to display the current currency.
src/components/Header.tsx
import currencyAtom from "src/atoms/currency-atom";
export default function Header() {
const currency = currencyAtom.value;
return (
<>
<div>Current Currency: {currency}</div>
</>
);
}
This will output: Currency: USD
We used currencyAtom.value
to get the current value of the atom.
Update the atom's value
Let's go further step and update the atom of the currency.
import currencyAtom from "src/atoms/currency-atom";
export default function Header() {
const currency = currencyAtom.value;
return (
<>
<div>Current Currency: {currency}</div>
<button onClick={() => currencyAtom.update("USD")}>USD</button>
<button onClick={() => currencyAtom.update("EUR")}>EUR</button>
<button onClick={() => currencyAtom.update("EGP")}>EGP</button>
</>
);
}
The currencyAtom.update
will update the atom's value, however this will not re-render the component.
The Atom State
Now let's see a scenario that we've a currency dropdown in our Header and another one is the Footer.
The trick here not only to re-render only the Header and the Footer only without rendering the entire layout, which relief us from using The Context Hook.
src/components/Header.tsx
import currencyAtom from "src/atoms/currency-atom";
import { useAtom } from "@mongez/react-atom";
export default function Header() {
const [currency, setCurrency] = useAtom(currencyAtom);
return (
<>
<div>Current Currency: {currency}</div>
<button onClick={() => setCurrency("USD")}>USD</button>
<button onClick={() => setCurrency("EUR")}>EUR</button>
<button onClick={() => setCurrency("EGP")}>EGP</button>
</>
);
}
We used useAtom
hook to get currency from the currency atom and to a state updater to update the atom's value.
It works exactly like useState
but the trick here it updates every component that listens to the atom
.
Let's create a Footer
component that listen to the currency atom's value
src/components/Footer.tsx
import currencyAtom from "src/atoms/currency-atom";
import { useAtom } from "@mongez/react-atom";
export default function Footer() {
const [currency] = useAtom(currencyAtom);
return (
<>
<div>Current Currency: {currency}</div>
<h1>This is footer</h1>
</>
);
}
Now whenever the currency's value is updated, the Footer component will be re-rendered for each update.
The Atom Value
Another way to listen to the atom's value is using useAtomValue
hook instead of useAtom
src/components/Footer.tsx
import currencyAtom from "src/atoms/currency-atom";
import { useAtomValue } from "@mongez/react-atom";
export default function Footer() {
const currency = useAtomValue(currencyAtom);
return (
<>
<div>Current Currency: {currency}</div>
<h1>This is footer</h1>
</>
);
}
Alternatively, we can get the value state directly from the atom itself using useValue
hook
import currencyAtom from "src/atoms/currency-atom";
export default function Footer() {
const currency = currencyAtom.useValue();
return (
<>
<div>Current Currency: {currency}</div>
<h1>This is footer</h1>
</>
);
}
In the next post we'll see how to work with atoms as objects and how to listen for single value change of the atom's objects using the atom watchers.
To Be Continued...
Top comments (4)
Enhancement this state management, then make another one :)
Prop name should be called key in my opinion to avoid confusion. Also what's the point when we have Jotai & Recoil?
Thanks for the reply Ivan, but why it should be called key, the object will not be used apart from the atom's utilites which doesn't allow either names.
Regarding what's the point of this package, well there are many reasons, on top of it the ease of use, also the watchers are very useful which will be in part two of the series.
Also, why not to make a new one?
I still think it should be called key because this is a pattern most people are familiar with. Also it does not mean that you mean the object key it means that it is an unique key. To your last point I think Jotai and Recoil cover everything.