✨Let me introduce to you: Jotai 👻
Jotai is a minimalistic but extremely powerful React State management library which makes state management simple as heck!
It's as simple as using a useState, but for your global state.
But it goes beyond that with its utils...
🧵
...and integrations with other state management libraries like React Query, XState, Valtio, Redux, Zustand, URQL.
But let's begin with the basics, and implement our own theme switcher 💡
Read on 👇
Setting it up!
jotai exports a Provider which you put at the root of your app(or the portion where you want jotai to work)
⚛️Atom
An atom is a small isolated piece of state. It basically holds the state in it.
Ideally, one atom contains very small data, although it's just a convention. You could still put all your state in one atom 🙂
Using an atom as a state is dead simple. It's very much like a useState, but you pass it an atom. Then it gives you the value and a setter, just like useState
OFC, we haven't used setTheme anywhere, so let's do that.
Now it is a theme switcher, but it's not practical yet....
An ideal theme switcher would go like this 👇
- Easily toggle state between different themes
- Persisted between page reloads
- Should work with Server Side rendering and Prerendering
So let's implement this👇
This hook is pretty robust and well tested and will work seamlessly. Note, we're setting light and dark classes on body. This is because we have declared our themes with CSS Variables on different classes on body
However, Jotai's got an ace up its sleeve. Jotai has a great set of utilities, which take care of some of the menial taks. One of these is atomWithStorage, which automatically syncs the state to localstorage.
Rewriting our hook above with atomWithStorage, we get 👇
It's 25% smaller. Not a big difference, but the main point is the complexity of our code is greatly reduced. Now the hook is basically just a useEffect applying class changes on theme change.
Much less error prone too, as majority of complex stuff is handled by a robust library.
Final usage of this hook ultimately. Pretty simple right? 😍
(No shade on Context, but I don't even wanna imagine how this hooks would be done with Context 🥲)
This was all about making something practical with Jotai. Now let me introduce you to some *DOPE AS HELL* features of Jotai. Get ready for this joyride 😉
1️⃣ Derived atoms
You compose many atoms together into one atom with Jotai's derived atoms. You get a `get` method which you can use to get values of different atoms while inside a derived atom's definition. Pretty dope feature I'd say
2️⃣ Async Atoms
Bring asynchronous behavior to your atoms. Using async atoms, atoms can do fetch calls, and basically a lot of asynchronous work 🤩
In this example, when you set value of fetchCountAtom, it'll literally fetch an API and set internal state value from the result
Now let's see some utils and, as the kids say nowadays, these are the real shit 😉
👇
1️⃣ atomWithStorage
We saw this before. This is basically an atom that stores your store in localstorage. This allows you to keep state between page reloads too 🪄
And it's Server Side Rendering friendly too, so works perfectly in your NextJS apps too
2️⃣ atomWithReset
Ever had that situation where you wanted to reset a state to its initial value and had to make an extra variable for it? No more needed with this atom. This gives you a function, which on call will reset an atom back to its initial value
3️⃣ selectAtom
selectAtom solves the big problem that comes with having a huge object or array in your atoms, and using that atom in multiple places in the app.
It allows you to focus on any descendent of the atom's value, hence saving re-renders
3️⃣ freezeAtom
This one is primarily for debugging, when you application state becomes too complex and reliant on a lot of atom. This basically freezes an atom so it can't be changed
4️⃣ waitForAll
Coming back to async atoms, sometimes you need to get data from multiple places, and wait for it come so you can assemble it into one piece. However, you also don't want to wait for one to come to fire the other. They both should fire at once.
Solution 👇
🤗Jotai fits in with others🫂
Yep, Jotai has official integrations with many popular state libraries, and rather than pretending to be the only thing in React ecosystem, it *encourages* working with other state libraries
To name a few
Immer
Optics
React Query
XState
Valtio
Immer, for one is very close to my heart. I am primarily a Svelte Guy, and in Svelte, you can just change a object-typed state's descendant property by just mutating it with obj.prop1.prop2.prop3 = 'whatever', whereas React's immutability makes is horribly hard
That is where Jotai's immer integration comes in. Immer allows you to mutate a state's copy, and immer will automatically reconcile all the changes internally, in a very React-like fashion.
Without Immer With immer
This brings us to the conclusion. Oooph, this was a long thread. Kudos for making it down here 😉💪🔥
I covered only a third of what Jotai does. And still we ended up with such a huge thread. Let that sink in. Feel how powerful Jotai truly is
Personally, I pick it for every P/React without batting an eye. With all these mindblowing features, it's a no-brainer.
If you prefer to read a blog post for more in-depth, here you go 100ms.live/blog/jotai-rea…
Also, to clarify: I'm not a creator/maintainer/contributor of Jotai or @pmndrs. I'm just a FREAKING HUGE fan of Jotai and want to spread the word around. This library has made my React codebases maintanable and code easier to write, this is the least I can do
And a big shoutout to @100mslive for letting me guest-post it on their blog! It was a fun collab 🤩
Share this Scrolly Tale with your friends.
A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.