Redux-Free State Management with Jotai

Cilikon
5 min readDec 18, 2020

The most tedious part when implementing Redux is the amount of boilerplate code that you need to write in order to handle the data flow between components and the Redux store. Redux itself was inspired by Flux, a data flow architecture introduced in 2014.

Since the release of React, we’ve seen a transition from the use of class components into the use of functional components with hooks. No offense to Redux and Flux (they are still awesome) but maybe it’s time to use a new pattern that takes advantage of React’s maturity.

Jotai is a state management library for React that will save you from boilerplate tears with its minimalistic API. And yes, you don’t need to create any actions, reducers, or dispatchers when using Jotai!

https://www.renatus-japan.co.jp/kox/kbs-v-world-tbs1.html
https://www.renatus-japan.co.jp/kox/kbs-v-world-tbs2.html
https://www.renatus-japan.co.jp/kox/kbs-v-world-tbs3.html
https://www.renatus-japan.co.jp/kox/kbs-v-world-tbs4.html
https://www.renatus-japan.co.jp/kox/kbs-v-world-tbs5.html
https://www.renatus-japan.co.jp/kox/kbs-v-world-tbs6.html
http://embrasser-h.com/pok/kbs-v-world-tbs1.html
http://embrasser-h.com/pok/kbs-v-world-tbs2.html
http://embrasser-h.com/pok/kbs-v-world-tbs3.html
http://embrasser-h.com/pok/kbs-v-world-tbs4.html
http://embrasser-h.com/pok/kbs-v-world-tbs5.html
http://embrasser-h.com/pok/kbs-v-world-tbs6.html

The mechanics of Jotai is very similar to React Context and Recoil, but even if you’re not familiar with either concept, this article will get you up to speed very quickly, because Jotai is very simple.

How Jotai works

To get started with Jotai, you need to install the library first:

npm install jotai
# or
yarn add jotai

Jotai replaces local state values in React components with atoms. An atom is simply an object that contains a piece of state. This object will then be passed into Jotai’s useAtom() hook so that your components can consume and update the value it currently stores. You can create an atom by calling the atom function:

import { atom } from 'jotai'const countAtom = atom(0)
const countryAtom = atom('Japan')

The atoms created above (0 and Japan) are now stored inside Jotai’s Provider , which is a component that you can use to wrap your React components:

import { Provider } from 'jotai'const Root = () => (
<Provider>
<App />
</Provider>
)

From the example above, all components beneath Provider can now access and update Jotai’s atoms.

You can access the atoms by using the useAtom hook, which will return the atom value and an updater function. Yes, it’s very similar to useState() hook:

import { useAtom } from 'jotai'function Counter() {
const [count, setCount] = useAtom(countAtom)
return (
<>
<h1>{count} </h1>
<button onClick={() => setCount((value) => value + 1)}>one up</button>
</>
);

And that’s all to it! You can call the atom from any other components, as long as that component is below the Provider component in the DOM tree.

Compared to a React-Redux application structure, a React-Jotai application has a much more straightforward structure. Here’s what a typical React-Redux structure looks like:

React-Redux in a nutshell

And here’s a simple diagram to illustrate how Jotai works:

React-Jotai in a nutshell

And here’s a live demo for you to inspect Jotai’s pattern. It’s recommended to separate atom declaration in its own file so that you can import your atoms into any consumer components.

And in case you’re wondering, the demo above is made using Bit, a platform that enables developers to share their JavaScript components. You can share React, Vue, Angular, and even Node.js modules with Bit:

Bit has a playground to render your component

You can use Bit (Github)to share, document, demo, and organize independent components from any projects.

Refactoring Redux app to use Jotai

The difficulty of refactoring your Redux application to use Jotai depends on the complexity of your current application itself, but you can use these identic examples as a reference:

Generally, the first place to refactor is to replace your Redux Provider with Jotai Provider. From this:

import { createStore } from "redux";
import { Provider } from "react-redux";
import App from "./App";const store = createStore(reducer);const Main = () => (
<Provider store={store}>
<App />
</Provider>
)

Into this:

import { Provider } from "jotai";
import App from "./App";const Main = () => (
<Provider>
<App />
</Provider>
)

There’s no longer any need to pass store into the Provider, but you do need to create atoms to replace the store mechanism. If you have a defaultState applied to your reducer, you can use it as a reference to create your atoms:

const defaultState = {
isPrimary: true,
};
const reducer = (state = defaultState, action) => {
// rest of the code omitted...
}

The reducer above can be replaced with a simple atom function:

import { atom } from "jotai";export const isPrimaryAtom = atom(true)

Now that you have the Provider and the Store part refactored, you only need to replace your Dispatcher and Action to complete the refactor. The general pattern of the Dispatcher should look like this:

import { useSelector, useDispatch } from "react-redux";function App() {
const isPrimary = useSelector((state) => state.isPrimary);
const dispatch = useDispatch();const title = isPrimary ? "Primary" : "Secondary";return (
<StyledButton
isPrimary={isPrimary}
onClick={() => {
dispatch({ type: "TOOGLE_BUTTON", payload: !isPrimary });
}}
>

You need to replace the import with Jotai’s useAtom and use the returned state updater to replace your Dispatcher:

import { useAtom } from "jotai";
import { isPrimaryAtom } from "./Atoms";
function App() {
const [isPrimary, setIsPrimary] = useAtom(isPrimaryAtom);const title = isPrimary ? "Primary" : "Secondary";return (
<StyledButton
isPrimary={isPrimary}
onClick={() => {
setIsPrimary(!isPrimary);
}}

The more complex your application, the harder it will be to refactor and switch your state management library, but the above guidelines should help you to create a refactoring plan.

Conclusion

Both Jotai and Recoil are great examples of how hooks have influenced React application development. Redux has been the most well-known state management library despite its tedious boilerplate because its benefits outweigh its costs. With Jotai, it’s now possible to have the benefits without paying the cost.

--

--