알고는 가자 - jotai

BackEnd_Ash.log·2024년 12월 10일
0

react

목록 보기
42/43

jotaiReact 상태 관리 라이브러리로, 간단하면서도 강력한 상태 관리를 제공합니다. jotai는 "atoms"라는 단위 상태 객체를 중심으로 작동하며, Recoil과 비슷하지만 더 가볍고 사용하기 쉬운 것이 특징입니다.


Jotai의 주요 특징

  1. 단순함:

    • useState와 비슷한 API로 작동하여 쉽게 배울 수 있습니다.
    • 복잡한 설정이나 프로바이더가 필요하지 않습니다.
  2. React 상태와 완벽한 통합:

    • useAtom 훅을 사용하여 상태를 읽고 업데이트할 수 있습니다.
    • React 컴포넌트 트리 안에서 자연스럽게 상태를 관리합니다.
  3. Fine-grained Re-renders:

    • 상태가 변경된 특정 컴포넌트만 리렌더링됩니다.
    • 전역 상태를 관리하면서도 성능이 우수합니다.
  4. Composable 상태:

    • 여러 개의 상태(atom)를 조합하여 파생된 상태를 생성할 수 있습니다.
    • 비동기 데이터도 쉽게 관리 가능합니다.
  5. 타입스크립트 지원:

    • TypeScript와의 강력한 통합을 제공합니다.
    • 타입 안전한 상태 관리를 할 수 있습니다.

핵심 개념

1. Atom

  • 상태의 최소 단위입니다. React의 useState와 비슷한 역할을 합니다.
  • atom을 사용해 상태를 정의하고 useAtom 훅으로 접근합니다.
import { atom, useAtom } from "jotai";

// Atom 정의
const countAtom = atom(0);

const Counter = () => {
  const [count, setCount] = useAtom(countAtom);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
    </div>
  );
};

2. Derived Atom (파생 상태)

  • 기존 atom을 기반으로 계산된 상태를 정의할 수 있습니다.
  • getter와 setter를 사용하여 파생 상태를 생성합니다.
import { atom, useAtom } from "jotai";

// 기본 atom
const countAtom = atom(0);

// 파생 상태 atom
const doubledCountAtom = atom((get) => get(countAtom) * 2);

const Counter = () => {
  const [count, setCount] = useAtom(countAtom);
  const [doubledCount] = useAtom(doubledCountAtom);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Doubled Count: {doubledCount}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
    </div>
  );
};

3. Async Atom

  • 비동기 데이터를 atom으로 관리할 수 있습니다.
  • atom 내부에서 Promise를 반환하여 데이터 로딩 상태를 처리합니다.
import { atom, useAtom } from "jotai";

// 비동기 atom
const fetchUserAtom = atom(async () => {
  const response = await fetch("https://api.example.com/user");
  const user = await response.json();
  return user;
});

const User = () => {
  const [user] = useAtom(fetchUserAtom);

  return <div>User: {user.name}</div>;
};

4. Writable Derived Atom

  • 파생된 atom을 수정 가능하게 정의할 수 있습니다.
const countAtom = atom(0);
const doubledCountAtom = atom(
  (get) => get(countAtom) * 2,
  (get, set, newValue) => {
    set(countAtom, newValue / 2); // countAtom 값을 업데이트
  }
);

const Counter = () => {
  const [doubledCount, setDoubledCount] = useAtom(doubledCountAtom);

  return (
    <div>
      <p>Doubled Count: {doubledCount}</p>
      <button onClick={() => setDoubledCount(10)}>Set to 10</button>
    </div>
  );
};

Jotai 2.10.1에서 주요 개선 사항

2.10.1은 Jotai의 최신 안정 버전 중 하나로, 아래와 같은 주요 특징을 포함합니다:
1. React 18 지원:

  • Concurrent Rendering과 같은 React 18의 새로운 기능과 호환됩니다.
  1. 개선된 TypeScript 지원:
    • 더 정교한 타입 추론 제공.
  2. 성능 최적화:
    • 파생 상태(atom) 계산 및 비동기 작업에서의 성능 개선.
  3. 새로운 기능:
    • 커스텀 Atom 설정을 위한 추가 유틸리티 제공.

Jotai vs. Redux vs. Recoil

FeatureJotaiReduxRecoil
Learning Curve쉬움중간중간
Boilerplate거의 없음많음적음
상태 구독세밀한 구독전체 리렌더링세밀한 구독
React와의 통합뛰어남뛰어남뛰어남
비동기 데이터 관리쉬움Middleware 필요쉬움
TypeScript 지원뛰어남뛰어남뛰어남

언제 Jotai를 사용해야 할까?

  • 상태 관리의 복잡성을 최소화하고 싶을 때.
  • Recoil처럼 세밀한 구독이 필요하지만 더 간단한 API를 원할 때.
  • 비동기 데이터 관리와 파생 상태 계산이 많은 프로젝트에서.
  • 작은 규모에서 중간 규모의 React 프로젝트.

Jotai는 React의 기본 상태 관리와 유사하면서도 전역 상태 관리에 더 적합한 옵션을 제공합니다. 성능 최적화와 간단함이 중요한 프로젝트에서 특히 유용합니다.

Jotai 사용법: 구체적인 설명

Jotai는 atom을 사용해 상태를 정의하고, React 컴포넌트에서 useAtom을 사용해 상태를 읽거나 업데이트합니다. 추가로 Jotai는 파생 상태, 비동기 상태, 커스텀 스토어 등을 지원하며, 이를 통해 상태 관리의 유연성을 제공합니다.


1. atom

atom은 Jotai의 상태 단위입니다. React의 useState와 비슷하지만 글로벌로 사용할 수 있습니다.

기본 사용법

import { atom, useAtom } from "jotai";

// Atom 정의
const countAtom = atom(0);

const Counter = () => {
  const [count, setCount] = useAtom(countAtom);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
    </div>
  );
};
  • atom은 상태를 저장하는 최소 단위입니다.
  • useAtom을 통해 atom을 읽고(setter 포함) 업데이트할 수 있습니다.

파생 상태 Atom

  • 다른 atom을 참조하여 계산된 상태를 정의할 수 있습니다.
const countAtom = atom(0);
const doubleCountAtom = atom((get) => get(countAtom) * 2);

const Counter = () => {
  const [count, setCount] = useAtom(countAtom);
  const [doubleCount] = useAtom(doubleCountAtom);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Double Count: {doubleCount}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
    </div>
  );
};

비동기 Atom

  • API 호출이나 비동기 작업도 Atom으로 관리할 수 있습니다.
const userAtom = atom(async () => {
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  return await response.json();
});

const User = () => {
  const [user] = useAtom(userAtom);

  return <div>User: {user.name}</div>;
};

2. getDefaultStore

Jotai는 상태를 관리하기 위해 Store를 사용합니다. 일반적으로는 기본 Store를 사용하며, getDefaultStore를 통해 이 기본 Store에 접근할 수 있습니다.

사용 예시

import { atom, getDefaultStore } from "jotai";

// Atom 정의
const countAtom = atom(0);

// 기본 Store 가져오기
const defaultStore = getDefaultStore();

// Store에서 직접 상태 읽기/업데이트
console.log(defaultStore.get(countAtom)); // 0
defaultStore.set(countAtom, 10); // 상태 업데이트
console.log(defaultStore.get(countAtom)); // 10

주요 기능

  • 상태 직접 읽기: get(atom)
  • 상태 직접 업데이트: set(atom, value)
  • 비동기 작업 처리: 비동기 Atom의 상태를 직접 관리 가능.

언제 사용하나요?

  • 컴포넌트 외부에서 상태를 읽거나 업데이트할 때.
  • 상태를 디버깅하거나 테스트할 때.

3. jotai/utils

Jotai의 유틸리티 라이브러리로, 상태 관리 작업을 더 쉽게 해주는 여러 가지 도구를 제공합니다.

주요 기능

1) atomWithStorage
  • 상태를 localStorage 또는 sessionStorage와 동기화.
import { atomWithStorage } from "jotai/utils";

// localStorage와 동기화된 atom 생성
const themeAtom = atomWithStorage("theme", "light");

const ThemeSwitcher = () => {
  const [theme, setTheme] = useAtom(themeAtom);

  return (
    <button onClick={() => setTheme((prev) => (prev === "light" ? "dark" : "light"))}>
      Current Theme: {theme}
    </button>
  );
};

2) atomWithDefault
  • 기본값을 계산하는 Atom을 생성.
import { atomWithDefault } from "jotai/utils";

const baseCountAtom = atom(5);
const doubleBaseAtom = atomWithDefault((get) => get(baseCountAtom) * 2);

const Counter = () => {
  const [doubleBase, setDoubleBase] = useAtom(doubleBaseAtom);

  return (
    <div>
      <p>Double Base: {doubleBase}</p>
      <button onClick={() => setDoubleBase(20)}>Set to 20</button>
    </div>
  );
};

3) splitAtom
  • 배열이나 객체를 각 요소별로 나누어 관리.
import { splitAtom } from "jotai/utils";

const listAtom = atom(["apple", "banana", "cherry"]);
const itemAtoms = splitAtom(listAtom);

const List = () => {
  const [items] = useAtom(itemAtoms);

  return (
    <ul>
      {items.map((itemAtom) => (
        <Item key={itemAtom} atom={itemAtom} />
      ))}
    </ul>
  );
};

const Item = ({ atom }) => {
  const [item, setItem] = useAtom(atom);

  return <li onClick={() => setItem("clicked")}>{item}</li>;
};

4) atomFamily
  • 동적으로 상태를 생성.
import { atomFamily } from "jotai/utils";

const countFamily = atomFamily((param) => atom(param));

const Counter = ({ id }) => {
  const [count, setCount] = useAtom(countFamily(id));

  return (
    <div>
      <p>Count {id}: {count}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
    </div>
  );
};

Jotai의 강력한 유틸리티 활용법

  1. atomWithStorage: 상태를 브라우저 저장소와 동기화.
  2. atomWithDefault: 기본값 계산 로직을 간결하게 정의.
  3. splitAtom: 배열이나 객체를 효율적으로 관리.
  4. atomFamily: 동적으로 Atom을 생성하여 확장성 있는 상태 관리.

요약

  • atom: Jotai의 상태 단위.
  • getDefaultStore: Jotai의 기본 Store를 가져와 상태를 직접 관리.
  • jotai/utils: 강력한 유틸리티로 상태 동기화, 파생 상태, 배열 관리 등을 지원.

이러한 도구를 활용하면 Jotai를 더욱 효율적이고 유연하게 사용할 수 있습니다. 필요에 따라 utils나 커스텀 로직을 작성해 상태 관리를 최적화하세요!

profile
꾸준함이란 ... ?

0개의 댓글