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.

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 into the , but you do need to create atoms to replace the store mechanism. If you have a 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 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 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.

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.