본문 바로가기

React

[React] Recoil

지난 Context-API에 이어, props drilling을 해결하기 위한 React의 전역 상태 관리 도구 중 하나인 Recoil에 대해서 알아보자.

 

[https://memo-code.tistory.com/67

 

[React] Context-API

React를 사용하다보면, 값을 전역적으로 관리하여야 할 때가 많다. 예를 들어, 테마나 언어 설정 등의 서비스 전반에서 공통적으로 사용되는 데이터 들이 그렇다.부모 자식 간의 관계가 존재하는

memo-code.tistory.com

 

 

Recoil?

Recoil은 전역 상태 관리를 돕는 React의 라이브러리이다.

Context와 달리 비동기 처리와 코드의 분리도가 높고, 하위 컴포넌트가 모두 리랜더링 되지 않는다는 장점이 있다.

 

Recoil은 기본적으로 Atom과 Selector로 구성되어 있으며, 이를 사용하기 위한 함수들이 존재한다.

 

Recoil은 React 패키지에 내장되어 있지 않으므로 설치를 해주어야한다.

npm install recoil

yarn add recoil

 

 

atom

atom은 Recoil에서 값(상태)를 저장하고 관리하기 위한 기본 형태이다.

상태의 저장과 읽기, 수정이 가능하다.

import { atom } from 'recoil';

export const themeState = atom({
  key: 'themeState',
  default: 'light',
});

 

Selector

Selector는 상태를 기반으로 계산된 값을 만드는 역할을 한다.

atom으로부터 상태를 받아 반환할 수도 있고, 외부 API 데이터 등의 비의존적이고 독립적인 Selector로의 활용도 가능하다.

// atom 이용
import { selector } from 'recoil';
import { themeState } from './atoms';

export const isDarkSelector = selector({
  key: 'isDarkSelector',
  get: ({ get }) => get(themeState) === 'dark',
});

// 외부 API 이용
import { selector } from 'recoil';

export const isDarkSelector = selector({
  key: 'isDarkSelector',
  get: async () => {
    const response = await fetch('/api/user/theme');
    const data = await response.json();
    
    return data.theme === 'dark';
  },
});

 

RecoilRoot

기본적으로 Recoil을 사용하기 위해선 최상위 컴포넌트에 RecoilRoot를 추가해주어야 한다.

import { RecoilRoot } from 'recoil';

function App() {
  return (
    <RecoilRoot>
      <Body />
    </RecoilRoot>
  );
}

export default App;

 

 

Recoil을 사용하기 위한 메서드들

useRecoilState

대상:   atom 

  • atom과 연결하여 상태를 읽고 쓸 수 있는 Hook
const [theme, setTheme] = useRecoilState(themeState);

 

useRecoilValue

대상:  atom & selector 

  • atom과 selector에서 상태를 읽기만 할 수 있는 Hook
const theme = useRecoilValue(themeState);
const isDark = useRecoilValue(isDarkSelector);

 

useSetRecoilState

대상: atom & selector 

  • atom과 selector에서 상태를 수정만 할 수 있는 Hook
  • selector에 set함수가 존재할 때만 가능
const setTheme = useSetRecoilState(themeState);
setTheme('dark');

 

useResetRecoilState

대상:  atom 

  • atom의 상태를 초기 상태로 되돌리는 Hook
const resetTheme = useResetRecoilState(themeState);
resetTheme();

 

useRecoilValueLoadable

대상:  selector 

  • selector를 비동기로 다룰 때 사용하는 Hook

selector는 비동기 연상 또한 수행할 수 있는데, 이때 사용되는 suspense의 대안이라고 할 수 있다.

 useRecoilValueLoadable() 이 반환하는 객체는 "state"와 "contents"가 있다.

"state"는 로딩 / 성공 / 실패 에 대한 상태를 다루며, "content"는 성공 시 데이터 혹은 실패 시의 에러 객체를 다룬다.

반환되는 예시 객체는 다음과 같다.

{
  state: 'loading' | 'hasValue' | 'hasError',
  contents: any
}

이를 활용하여 비동기 처리에 대한 작업을 할 수 있다.

 

import { useRecoilValueLoadable } from 'recoil';
import { isDarkSelector } from './selectors';

function ThemeStatus() {
  const loadable = useRecoilValueLoadable(isDarkSelector);

  if (loadable.state === 'loading') {
    return <p>테마 정보를 불러오는 중입니다...</p>;
  }  // 혹은 스피너

  if (loadable.state === 'hasError') {
    return <p>에러가 발생했습니다: {loadable.contents.message}</p>;
  }

  const isDark = loadable.contents;

  return (
    <div>
      나의 테마: {isDark ? '다크 모드' : '라이트 모드'}
    </div>
  );
}

 

 

 

 

 

'React' 카테고리의 다른 글

[React] Zustand  (0) 2025.07.02
[React] Tailwind CSS  (0) 2025.06.04
[React] Context-API  (0) 2025.05.23
[React] React Router 페이지 접근 권한  (1) 2024.11.21
[React] useContext  (0) 2024.11.20