Jotai란?
- React 상태관리 라이브러리 중 하나로 비교적 매우 간단하고 작은 단위로 전역 상태 관리가 가능
- 매우 작은 3kb의 번들 사이즈와 타입스크립트에 지향적
- Jotai는 React.js, Next.js, React Native에서 사용이 가능
jotai의 기본 사용법
기본적으로 Jotai는 React 내의 state, useState와 유사한 모양이기 때문에 쉽게 입문할 수 있습니다. 전역 관리 atom을 생성하고, 생성된 atom을 컴포넌트 내에 불러와 사용한다고 생각하면 됩니다.
1. atom
: atom을 생성하고 괄호 안에 초기값을 넣을 수 있습니다.
const counter = atom(0);
2. useAtom(read/write)
: 생성된 atom을 불러와서 useState와 동일하게 사용이 가능합니다.
const [count, setCount] = useAtom(counter);
3. useSetAtom(write)
: 생성된 atom의 값을 update만 할 때 사용합니다.
const counterWriteOnly = useSetAtom(counter);
4. useAtomValue(read)
: 생성된 atom의 값을 read만 할 때 사용합니다.
const counterReadOnly = useAtomValue(counter);
✅ useSetAtom, useAtomValue는 각각 읽기, 쓰기만 가져와서 사용하기 때문에 useAtom과 다르게 재랜더링 하지 않는 장점이 있습니다.
< 실습 >
// store/counterAtom.tsx
import { atom } from "jotai";
export const counter = atom(0);
// components/CounterControl.tsx
import { counter } from "@/store/counterAtom";
import { useAtom } from "jotai";
import * as S from "./counterControl.style";
const CounterControl = () => {
const [count, setCount] = useAtom(counter);
const handlePlus = () => {
setCount((prev) => prev + 1);
};
const handleMinus = () => {
setCount((prev) => prev - 1);
};
const handleReset = () => {
setCount(0);
};
return (
<S.MainContainer>
<h1>{count}</h1>
<S.ButtonContainer>
<S.Button onClick={handleMinus}>-</S.Button>
<S.Button onClick={handleReset}>reset</S.Button>
<S.Button onClick={handlePlus}>+</S.Button>
</S.ButtonContainer>
</S.MainContainer>
);
};
export default CounterControl;
// components/CounterDisplay.tsx
import { counter } from "@/store/counterAtom";
import { useAtomValue, useSetAtom } from "jotai";
import * as S from "./counterControl.style";
const CounterDisplay = () => {
const counterReadOnly = useAtomValue(counter);
const counterWriteOnly = useSetAtom(counter);
const handleTenPlus = () => {
counterWriteOnly((prev) => prev + 10);
};
const handleTenMinus = () => {
counterWriteOnly((prev) => prev - 10);
};
return (
<S.MainContainer>
<h1>{counterReadOnly}</h1>
<S.ButtonContainer>
<S.Button onClick={handleTenMinus}>- 10</S.Button>
<S.Button onClick={handleTenPlus}>+ 10</S.Button>
</S.ButtonContainer>
</S.MainContainer>
);
};
export default CounterDisplay;
// pages/index.tsx
import Head from "next/head";
import Image from "next/image";
import { Geist, Geist_Mono } from "next/font/google";
import styles from "@/styles/Home.module.css";
import CounterControl from "@/components/CounterControl";
import CounterDisplay from "@/components/CounterDisplay";
export default function Home() {
return (
<>
<Head>
// ....
</Head>
<div
className={`${styles.page} ${geistSans.variable} ${geistMono.variable}`}
>
<main className={styles.main}>
<CounterControl />
<CounterDisplay />
</main>
<footer className={styles.footer}>
// ...
</footer>
</div>
</>
);
}
'인턴' 카테고리의 다른 글
React와 styled-components로 만드는 커스텀 토글 버튼 (0) | 2025.03.25 |
---|---|
useMemo와 useCallback (0) | 2025.03.25 |
[ Troubleshooting🛠️ ] GNB 자동 스크롤과 페이지 이동 기능 통합 (0) | 2025.03.25 |
[ Troubleshooting🛠️ ] Map 객체와 배열 간 타입 불일치 (0) | 2025.03.25 |
[ Troubleshooting🛠️ ] HTML <picture>과 <source> 태그 활용하기 (0) | 2025.03.25 |