jotaish
v1.0.3
Published
Better Jotai DX with Jotaish 🃏
Downloads
8
Readme
Better Jotai DX with Jotaish
- Get started
- The Problem
- The Solution
- Adoptation
- How to use
- Return value according to Atom type
- Size
- LICENSE
Get started
pnpm i jotaish
The Problem
In Short, as scale of number of atoms becomes larger, managing them becomes more harder.
Large scale problem list
- When using atom, you might have to declare and naming the state and setter's name everytime using it.
- Custom hook logic might reduce this effort. But that means each atom require own custom hook. It is not DRY.
- You should remember declared atom's name to import it with vscode autocompletion.
The Solution
Consistent
name
andimport
with magical ✨autocompletion✨
- Categorize atoms by usage (📢 user requirements)
- Autocomplete atom's name
- Autocomplete atom-state-setter's name
Adoptation
Without Jotaish🃏
// ❌ import each atoms, name state-setter
import { useAtom } from "jotai";
import { count } from "@atoms/count";
const [count, setCount] = useAtom(count);
// ❌ use custom hook for each atoms
import { useCountHook } from "@atoms/count";
const { count, setCount } = useCountHook();
With Jotaish🃏
// ✅ use magical ✨autocompletion✨.
import { $, useStore } from "@atoms/index";
const { Count, setCount } = useStore($("count"));
$
function autocompletes all atom's name
How to use
STEP1: Make Atom Store
at */atom/countAtoms.ts
import { atom } from "jotai";
const count = atom(1);
const isCountEven = atom((get) => get(count) % 2 === 0);
at */atom/index.ts
const Store = {
count,
isCountEven,
} as const; // ✅ It is much safer with const-assertion
STEP2: Make $
function and export $
, useStore
function in one file
at */atom/index.ts
import { count, isCountEven } from "./countAtoms";
import { getStore, useStore } from "jotaish";
const Store = {
count,
isCountEven,
} as const;
const $ = getStore(Store); // ✅ You can choose diffrent name like _, _s!
export { $, useStore };
STEP3: Use atoms in the component
import { useStore, $ } from "@atoms/index";
const Counter = () => {
const { Count, setCount } = useStore($("count"));
const { IsCountEven, setIsCountEven } = useStore($("isCountEven"));
return (
<div>
<h1>Count: {Count}</h1>
<h2>{IsCountEven ? "Even" : "Odd"}</h2>
<button onClick={() => setCount((c) => c + 1)}>Plus 🔺</button>
<button onClick={() => setCount((c) => c - 1)}>Minus 🔻</button>
</div>
);
};
Return value according to Atom type
All
Return
value is 🃏-fully-jotai-typed-🃏
CASE1. Primitive, Read-Write Atom
// primitive 🟩
const count = atom(1);
// read-write 🟩
const increaseCountTextAndAction = atom(
(get) => `count is: ${get(count)}`,
(get, set) => set(count, get(count) + 1)
);
🔔 Returns
state
&setter
&atom
itself
const { Count, setCount, atomOfCount } = useStore($("count"));
CASE2. Read Only Atom
// read-only 🟨
const isEven = atom((get) => get(count) % 2 === 0);
🔔 Returns
state
&atom
itself
const { IsEven, atomOfIsEven } = useStore($("isEven"));
CASE3. Write Only Atom
// write-only 🟦
const updateCount = atom(
null, // for specifying writing atom
(get, set, newCount: number) => set(count, newCount)
);
🔔 Returns
state
&setter
&atom
itself
But state
= null
, Just ignore it and don't destruct.
const { setUpdateCount, atomOfUpdateCount } = useStore($("updateCount"));
Size
# ✅ ESM ======================================
dist/jotaish.es.js 0.31 KiB / gzip: 0.22 KiB
# ✅ UMD ======================================
dist/jotaish.umd.js 0.54 KiB / gzip: 0.35 KiB
LICENSE
MIT