React Recoil로 상태관리 방법

ReactrecoilatomselectorRecoilRootuseRecoilStateuseRecoilValueuseSetRecoilStateuseResetRecoilStateuseMemo
avatar
2025.04.10
·
3 min read

모듈 설치

npm i recoil

RecoilRoot 지정

  • recoil 상태를 사용하는 컴포넌트는 부모 트리 어딘가에 나타나는 RecoilRoot 가 필요하다.

  • 루트 컴포넌트가 RecoilRoot를 넣기에 가장 좋은 장소다.

index.ts

import ReactDOM from "react-dom/client";
import { RecoilRoot } from "recoil";
import App from "./App";

const rootEl = document.getElementById("root");
const root = ReactDOM.createRoot(rootEl);

root.render(
  <RecoilRoot>
    <App />
  </RecoilRoot>
);

Atom & Selector 설정

Atom

  • Atom은 상태(state)의 일부를 나타낸다.

  • Atoms는 어떤 컴포넌트에서나 읽고 쓸 수 있다.

  • atom의 값을 읽는 컴포넌트들은 암묵적으로 atom을 구독한다.

  • 그래서 atom에 어떤 변화가 있으면 그 atom을 구독하는 모든 컴포넌트가 리렌더링한다.

Selector

  • Selector는 파생된 상태(derived state)의 일부를 나타낸다. 파생된 상태는 상태의 변화다. 파생된 상태를 어떤 방법으로든 주어진 상태를 수정하는 순수 함수에 전달된 상태의 결과물로 생각할 수 있다.

  • useMemo와 유사하다

/atoms.ts

import { atom } from 'recoil';

// count atom
export const countAtom = atom<number>({
  key: 'count',
  default: 1
});
export const countTextSelector = selector({
  key: 'count-text',
  get: ({ get }) => {
    const value = get(countAtom);
    return '현재 카운트는 ' + value + '입니다.';
  }
});

// user atom
export interface IUser {
  id: number;
  name: string;
  age?: number;
  job?: string;
}
export const userAtom = atom<IUser>({
  key: 'user',
  default: {
    id: 1,
    name: '홍길동',
    age: 26,
  }
});

Atom 값 사용

atom의 값을 읽기 또는 쓰기를 하기 위하여 아래와 같은 Recoil Hook을 사용할 수 있다.

  • atom 값 읽기/쓰기 (useState와 유사) : useRecoilState

  • atom 값 읽기 (getter만 사용) : useRecoilValue

  • atom 값 쓰기 (setter만 사용) : useSetRecoilState

  • atom 값 default값으로 초기화 : useResetRecoilState

page.tsx

import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { countAtom, countTextSelector } from '@/atoms';

export default () => {
  // [number, (value: number) => void | ((currentValue: number) => number) => void]
  const [count, setCount] = useRecoilState(countAtom);
  // number
  const countValue = useRecoilValue(countAtom);
  // (value: number) => void | ((currentValue: number) => number) => void
  const countSetter = useSetRecoilState(countAtom);
  // string
  const countText = useRecoilValue(countTextSelector);

  return (
    <div>
      count : {count}
      countValue : {countValue}
      countText : {countText} 
    </div>
  )
}

결과물

count : 0
countValue : 0
countText : 현재 카운트는 0입니다.






- 컬렉션 아티클