Jotai
๋ฆฌ์กํธ ์ํ๊ด๋ฆฌ๋ฅผ ์ฝ๊ฒ
Apr 25, 2023
๋ค์ด๊ฐ๋ฉฐ
React๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํด ๋ง์ด ์ฌ์ฉ๋๋ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๊ทธ๋ฌ๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋, ๋ณต์กํ ์ํ ๊ด๋ฆฌ ๋ฌธ์ ๋ฅผ ๋ค๋ฃจ์ด์ผํ๋ ๊ฒฝ์ฐ๊ฐ ์ข ์ข ๋ฐ์ํฉ๋๋ค.
์๋ฅผ ๋ค๋ฉด ์ต์์ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ๋ณด๋ด์ฃผ๋ ๋ฐ์ดํฐ๊ฐ ๋ช๋จ๊ณ์ ์์ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ๋์ด์ผ ํ๋ฉฐ ์ ๋ฌ ๋ฐ์ ๋ฐ์ดํฐ๋ก ์ธํด์ ์์์ ์ํ๊ฐ์ด ์ ๋ฐ์ดํธ ๋์ด์ผ ํ ๋โฆ ์ฝ์ง ์๊ฒ ์ฃ ?
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฒ ๊ธ์์๋ Jotai๋ผ๋ React ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํด ๊ฐ๋จํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
Jotai๋?
React์ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ค ํ๋์
๋๋ค.
Jotai๋ ๋ป์ ์ผ๋ณธ์ด๋ก โ์ํโ๋ผ๋ ์๋ฏธ์ธ๋ฐ์
Jotai๋ฅผ ์ฌ์ฉํ์๋ ๋ฆฌ์กํธ ์ ํ๋ฆฌ์ผ์ด์
์์ ๋น๊ต์ ๊ฐ๊ฒฐํ๊ณ ์ฝ๊ฒ ์ ์ญ ์ํ๊ด๋ฆฌ๋ฅผ ํ ์ ์์ต๋๋ค.
Jotai๋ ๋ฆฌ์ฝ์ผ์์ ์๊ฐ์ ๋ฐ์ ์ํ ๋ฏน ๋ชจ๋ธ๊ณผ ํจ๊ป bottom-up ๋ฐฉ์์ผ๋ก ์ ๊ทผํฉ๋๋ค. ์ํฐ๊ณผ ํจ๊ป ์ํ๋ฅผ ์์ฑํ๊ณ ์ํฐ ์์กด์ฑ์ ๋ฐ๋ผ ๋ ๋๋ง ์ต์ ํ๋ฅผ ํ๋๋ฐ, ์ด ๋ฐฉ์์ ํตํด ๋ฆฌ์กํธ ์ปจํ ์คํธ์ ๋ฆฌ๋ ๋๋ง ์ด์๋ฅผ ํด๊ฒฐํ๊ณ , ๋ฉ๋ชจ์ด์ ์ด์ ์ ์์กด๋๋ฅผ ์ค์ผ์ ์๋ค๊ณ Jotai๊ณตํ์ ์ค๋ช ๋์ด ์์ต๋๋ค.(์์ง recoil์ ์ฌ์ฉํด ๋ณด์ง ๋ชปํ์ฌ ์ถํ์ ๊ธฐํ๊ฐ ์์ผ๋ฉด recoil์ ๋ํด์ ์์๋ณด๊ฒ ์ต๋๋ค)
ํน์ง
- ์ต์ํ์ API
- TypeScript ๊ธฐ๋ณธ ๋ด์ฅ
- ์์ ๋ฒ๋ค ํฌ๊ธฐ
- ๋ง์ ์ถ๊ฐ ์ ํธ๋ฆฌํฐ ๋ฐ ๊ณต์ ํตํฉ
- ๋ฆฌ์กํธ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅ
- Next.js ๋ฐ React Native ์ง์
- atomicํ ์ํ ๊ด๋ฆฌ ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑ
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
Jotai๋ ์ฌ์ฉ๋ฒ์ด ์๋์ ์ผ๋ก ์ฝ๊ณ ๊ฐ๊ฒฐํ ํธ์ธ๋ฐ์ ์๋์ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ์ค๋ช ๋๋ฆฌ๊ฒ ์ต๋๋ค.
์ฐ์ npm์ ์ด์ฉํด Jotai๋ฅผ ์ค์นํด ์ค๋๋ค.
npm install jotai
๋ค์์ Jotai์ atom์ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ์์ฑํ๋ ์ฝ๋์ ๋๋ค.
import { atom } from 'jotai';
const countAtom = atom(0);
์ ์ฝ๋๋ countAtom ์ด๋ผ๋ ์ด๋ฆ์ ์ํ๋ฅผ ์์ฑํ๋ฉฐ, ์ด๊น๊ฐ์ผ๋ก 0์ ์ค์ ํฉ๋๋ค.
์ด์ ์ด ์ํ๋ฅผ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import { useAtom } from 'jotai';
function Counter() {
const [count, setCount] = useAtom(countAtom);
function increment() {
setCount((count) => count + 1);
}
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
์์ ์์ ์ฝ๋์์๋, countAtom์ด๋ผ๋ ์ํ(atom)๋ฅผ ์ ์ํ๊ณ , useAtom ํ ์ ์ฌ์ฉํ์ฌ ํด๋น ์ํ๋ฅผ ์ฝ๊ณ ๋ณ๊ฒฝํฉ๋๋ค. Counter ์ปดํฌ๋ํธ์์๋ count ์ํ๋ฅผ ๋ ๋๋งํ๊ณ , ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ํตํด ํด๋น ์ํ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.
ํ๋ก์ ํธ์ ์ ์ญ์ผ๋ก ๊ด๋ฆฌ๋ ์ํ๊ฐ๋ค์ ์ฑ๊ฒฉ์ ๋ง๋๋ก ํ๊ณณ์ ์ ์ํด๋์ด ํ์์ ํด๋น ์ปดํฌ๋ํธ์์
import { useAtomValue } from 'jotai';
const count = useAtomValue(countAtom);
useAtomValue(read)์ฝ๊ธฐ
import { useSetValue } from 'jotai';
const count = useSetAtom(countAtom);
useSetAtom(write)์ฐ๊ธฐ
์์๊ฐ์ ํํ๋ก๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ด๋ ๊ฒ Jotai ์๋ ์ธ๊ฐ์ง ํจํด์ด ์์ต๋๋ค.
- ์ฝ๊ธฐ(read),์ฐ๊ธฐ(write)
- ์ฝ๊ธฐ(read)
- ์ฐ๊ธฐ(write)
์ด๋ ๊ฒ ์์ฑ์ ๊ฐ๊ฐ ์ฝ๊ธฐ, ์ฐ๊ธฐ๋ง ๊ฐ์ ธ์์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ useAtom ๊ณผ ๋ค๋ฅด๊ฒ ์ฌ๋๋๋ง ํ์ง ์๋ ์ฅ์ ์ด ์์ต๋๋ค.
๋งค์ฐ ๊ฐ๋จํฉ๋๋ค ์ฌ์ฉ ๋ฐฉ์์ด ๋ฆฌ์กํธ์ useState
hook๊ณผ ๊ฑฐ์ ํก์ฌํ์ฃ ํ์ง๋ง useState์ ๋ค๋ฅด๊ฒ ํน์ ์ปดํฌ๋ํธ์ ๊ตฌ์๋์ด์์ง ์์ต๋๋ค.
export const count = atom(0);
์์ ๊ฐ์ด export
์ ์ธ์ ํตํด ์ด๋์๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ํด๋น atom๊ฐ์ ์ ๊ทผ์ด ๊ฐ๋ฅํ์ฃ
์ธ์ ์ฌ์ฉํ๋ฉด ์ข์๊น?
jotai๋ Redux๋ MobX์ ๊ฐ์ ๋ค๋ฅธ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ณด๋ค ์๋์ ์ผ๋ก ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ธฐ ๋๋ฌธ์, ์์ ๊ท๋ชจ์ ํ๋ก์ ํธ์์ ์ฌ์ฉํ๊ธฐ ์ ํฉํฉ๋๋ค.
jotai๋ Redux๋ MobX์ ๊ฐ์ ๋ค๋ฅธ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋นํด ๋ณด๋ค ๋จ์ํ๊ณ ์ง๊ด์ ์ธ API๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋จํ ์ํ ๊ด๋ฆฌ์ ์ ํฉํฉ๋๋ค.
jotai๋ React์ ์๋ก์ด Context API์ ํจ๊ป ์๋ํ๋ฉฐ, Context API์ ๊ฐํธํ ์ฌ์ฉ๋ฒ์ ์ด์ฉํ์ฌ ์ํ ๊ด๋ฆฌ๋ฅผ ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ Redux๋ MobX์ ๊ฐ์ ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
jotai๋ ๋ถ๋ณ์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ Immer์ ํจ๊ป ์ฌ์ฉํ๋ฉด์๋ ์ํ์ ๋ถ๋ณ์ฑ์ ๋ณด์ฅํ๋ฉด์ ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
jotai๋ ์ํ ๋ณํ๋ฅผ ์ถ์ ํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด์ค๋๋ค. ์ด๋ ๋๋ฒ๊น ์ด๋ ๊ฐ๋ฐ ๊ณผ์ ์์ ๋์์ด ๋ฉ๋๋ค.
๋ง์น๋ฉฐ
๊ฐ๋จํ๊ฒ ๋ฆฌ์กํธ์ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ Jotai์ ๋ํด์ ์์๋ดค๋๋ฐ์
๋ฆฌ์กํธ์์ useState์ context api ๋ง์ผ๋ก ์ํ๊ด๋ฆฌ๋ฅผ ์งํํ๊ฑฐ๋ ๊ณ ๋ ค์ค์ด๋ผ๋ฉด Jotai๋ฅผ ๋์ ํด ๋ณด๋ ๊ฒ๋ ์ข์๊ฒ ๊ฐ์ต๋๋ค. ๋ฌผ๋ก ๊น์ด ํ๊ณ ๋ค์ด ๋ด๋ถ๊ตฌ์กฐ ๋ฐ ์ต์ ํ ๋ถ๋ถ๊น์ง ์ดํดํ๊ณ ์ฌ์ฉํ๊ธฐ์๋ ์ฝ์ง ์๊ฒ ์ง๋ง ์๋์ ์ผ๋ก ๋ฎ์ ๋ฌ๋์ปค๋ธ์ ์ ๊ณต๋๋ ์ ํธ๋ค์ด ๋ค์ํ๋ฐ๋ ๋ถ๊ตฌํ๊ณ ์ด๋ฒ๋ค ์ฌ์ด์ฆ๊ฐ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋นํด ๋ฎ์ํธ์ธ๊ฑด ์ถฉ๋ถํ ๋งค๋ ฅ์ ์ธ ๋๊ตฌ๋ผ ์๊ฐ๋ฉ๋๋ค.