- Lab
- Core Tech

Guided: State Management with Jotai
Learn how to manage state in React with Jotai. In this hands-on Code Lab, you'll build a to-do list app from scratch, mastering atoms, derived state, local storage persistence, and centralized store management. Perfect for developers looking to simplify state management in their apps.

Path Info
Table of Contents
-
Challenge
Introduction
In this lab, you'll be creating a simple todo list app using React and Jotai.
To do this, you will utilize various Jotai hooks and features to build up an app that maintains state using Jotai, stores todo list items in a local storage, and enables filtering. You will explore and use Jotai's four core concepts:
atom
,useAtom
,Store
, andProvider
. Additionally, you'll work with the specializeduseAtomValue
anduseSetAtom
hooks, which help optimize performance by preventing unnecessary component re-renders.You will also learn how to use
atomWithStorage
to store data in the browser's local storage, and use atoms that are derived values rather than just state.The lab is already set up with a React project using basic React concepts, not using Jotai. You can find the basic
TodoList
component insidecomponents/TodoList.js
.You will need to open the app in a separate browser tab so that you can see the document title in the text of the tab. Whenever you see this link: Go to your app, you can click it open the app in a new browser tab.
To run the app:
- Click the Run at the bottom of the Terminal.
- Run the app by following the link Go to your app.
Move to the next step to begin!
-
Challenge
Todo List Data
In this first step of the lab, you will use Jotai's
atom
to store the state for the todo list app, instead of React'suseState
. Now you will use thatatom
to output the todo list.There is already a starter code in the
state\todoListAtom.js
file, which exports three variables. For this step, you will only update thetodoListAtom
variable in thetodoListAtom.js
file.One core concept in Jotai is called an
atom
, which represents a piece of state for the application. You will start by replacinguseState
withatom
. Note that you'll centralize the calls toatom
in thestate\todoListAtom.js
file.To run your app you can go to your app. You won't get rid of
useState
just yet, so that the app doesn't error. Later you will get rid of those calls after you've replaced the functionality.Now that you have the state stored as an atom, you’ll use it to display the todo list. Your todo list is now pulling from the Jotai atom! Notice though that, while the app doesn't error, nothing else works.
This is because the rest of the functionality is tied to the data in
useState
, not the data in the atom. You will fix that as you update the rest of the app. -
Challenge
Add a Todo
The
AddTodo
component was previously using props to add new items to the todo list, and this state was managed locally withuseState
. You're now transitioning to using the centralizedtodoListAtom
to manage the state across components.In this step, you will use the
useSetAtom
hook, which is used when you are only setting (not reading) a value from an atom. Since you are only adding a todo in theAddTodo
component, you don't need to read from the atom. TheuseSetAtom
hook helps you avoid unnecessary re-renders by specifying that you are only updating the atom, and the component's output never uses the atom's data. Now when you go to your app you can add new todos! However when you refresh the page, the data resets. That was true when you started. Next you'll see how Jotai easily helps you fix that. -
Challenge
Local Storage
Now that you have transitioned the state management for the todo list to Jotai, you want to ensure the state is persistent. You'll complete the remaining functionality, such as marking todos as complete and deleting them, a little later.
State persistence means that when users refresh the page, their todo items should still be there. You will accomplish this by storing the todos in the browser's local storage and updating the local storage whenever the todos are updated.
This is quite simple, thanks to Jotai's
atomWithStorage
. Now when you go to your app you can add new todos and when you refresh the page, the data persists! Next you'll adjust how you're storing your state, utilizing Jotai'sStore
functionality. -
Challenge
Jotai Stores
Jotai allows you to create a centralized store to manage your atoms. This centralized store can help make your app more scalable and maintainable, particularly as the number of atoms grows. It also helps in debugging, as all the atoms are accessed through a single store.
Atoms are really just definitions of your state, stores let you control where that state is stored and how it is used.
You can create a store with
createStore
. You then can use that store using the JotaiProvider
. You can even use different stores in different parts of your app by utilizing theProvider
element in your JSX. By creating aStore
and using aProvider
, you are ensuring atoms referenced by descendants of theProvider
are all referencing data in thatStore
. You can have multipleStores
in your app.If you need to access store data outside of React, like in a utility function that does other work, you can use
store.get
andstore.set
to get and set values.You don't really need that here, but in the next task you will try using it. When you go to your app you should see the
Store
data being logged to the console (more than once since you're in development mode in React, so components are called twice).You won't use
store.get
orstore.set
for the rest of the lab, but it's good to know that they are there. Now you will get the rest of the functionality up and running! -
Challenge
Update Todos
You are successfully adding todos to the
Store
. In this step, you will fix the complete and delete functionalities of the todo list app. ThetoggleComplete
function has been provided for you so you can examine it. Note that when you go to your app you can now toggle the status of the todos (completed or undo)!Now you will enable the ability to delete todos. The
removeTodo
function has been provided in this case as well so you can examine it. The functionality of the todo list app is nearly complete! Now you need to enable filtering todos, using Jotai atoms. -
Challenge
Filtered Todos
In this last step of the lab, you'll enable filtering. Jotai allows for derived atoms, meaning atoms that return a value from a function, based on the actual stored data. Filtered data is a subset of the total data, thus perfect for a derived atom. You are using a string to specify what filter you want, and it has now been defined using
atom
and will be stored in the Jotai store. Now that you have a filter atom inFilter.js
usingfilterListAtom
, you will create a derived atom, which will be a function that will return a subset of todos based on which filter is chosen.Jotai will update the derived atom whenever the atoms it uses are changed. In this case, the derived atom will use
filterListAtom
, so whenever that you change the chosen filter the derived atom will update. Note the derived atom usestodoListAtom
andfilterAtom
to determine what todos to return. You now just need to use thefilteredTodosAtom
as the data poweringTodoList.js
to finish the lab!You will use two different Jotai hooks.
useAtomValue
only reads the value from the atom, anduseSetAtom
only returns a function to set the atom. You will useuseAtomValue
to read from the derived atom, anduseSetAtom
to update the todos.Using these hooks helps Jotai to determine when it can avoid React re-renders. When you go to your app you should now see that the todo list app is completely functional!
If you like, you can now remove all the
useState
code inApp.js
and update the JSX by removing references to the replaced functions.The todo list app is complete and using Jotai! Congratulations, well done!
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.