An introduction to atomic state management libraries in React
Tags: javascript, react, tutorial
Published: 2021-11-08 11:42:33

## Introduction

Atomic state management libraries are growing. Fast. As you can see in this graph from [npmtrends](https://www.npmtrends.com/jotai-vs-recoil), the two most famous libraries [Recoil](https://recoiljs.org/) and [Jotai](https://jotai.pmnd.rs/) were almost unknown last year, and now count respectively **240k and 35k downloads per week**:

![Jotai VS Recoil](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7hwtx58ko9ymvcog6r5.png)

I've also open-sourced a new atomic library called [Particule](https://github.com/QuiiBz/particule), which has some new interesting features such as [custom `atom`  functions with hooks](https://github.com/quiiBz/particule#custom-atom-with-hooks).

## But what is atomic state management?

Ha, that's a good question. From [Recoil's docs](https://recoiljs.org/docs/introduction/core-concepts/#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.

An atom represents a piece of state that you can read and update anywhere in your application. Think of it as a `useState` that can be shared in any component.

This approach provides many benefits, mainly:

### Avoid unwanted re-renders and computations

You won't anymore pass state values and update functions via `props`, nor trigger the whole tree of components from a context's consumer. **Only components subscribed to the atom's value will update**.

Take a look at this example using [Particule](https://github.com/QuiiBz/particule):

``` tsx
const textAtom = atom('Hello world!')

function Text() {
  const text = useGetAtom(textAtom)

  return <p>{text}</p>
}

// Won't re-render!
function Button() {
  const setText = useSetAtom(textAtom)

  return <button onClick={() => setText('Updated!')}>Update</button>
}

// Won't re-render!
export default function App() {
  return (
    <>
      <Text />
      <Button />
    </>
  )
```

Only `<Text />` will re-render, even if `<Button />` also uses the atom. But there's a difference between the two: `<Button />` **isn't subscribed to updates, because it uses `useSetAtom`** and only retrieves a setter function (similar to the one in `useState`. On the contrary, `<Text />` is subscribed to updates because it uses `useGetAtom` to retrieve the value.

### Compose atom from other atoms

Derived (or composed) atoms are atoms made from other atoms. They subscribe to each atom that they depend on, and such automatically trigger a re-render when needed.

This can be made using [selectors](https://recoiljs.org/docs/basic-tutorial/selectors) in Recoil, and is even simpler in Jotai and Particule. This example is made with [Particule](https://github.com/QuiiBz/particule):

```tsx
const eurosAtom = atom(10)
const dollarsAtom = atom(get => get(eurosAtom) * 1.15)

function App() {
  const [euros, setEuros] = useAtom(eurosAtom)
  const [dollars, setDollars] = useAtom(dollarsAtom)

  return (
    <>
      <input onChange={({ target }) => setEuros(target.value)} value={euros} />
      <input onChange={({ target }) => setDollars(target.value)} value={dollars} />
    </>
  )
}
```

When `eurosAtom` changes, `dollarsAtom` is re-calculated since it is subscribed using `get` and re-render the component once.

There are many other interesting topics with atomic state management libraries, such as `<Suspense />` support for async, helper `atom` functions to add new functionalities...

So feel free to comment down below if you want more articles on this, and you can check out the GitHub repository of the libraries I mentioned:

- [Particule](https://github.com/QuiiBz/particule) (looking for feedback!)
- [Recoil](https://github.com/facebookexperimental/Recoil) (created by Facebook)
- [Jotai](https://github.com/pmndrs/jotai) (created by Poimandres)