recoil 은 상태관리 라이브러리이다.

react-redux 에 비해 코드가 간결해서 사용하기 쉽다.


설치

npm i recoil


atoms.js

atom 이라는 전역 객체를 만들어서 데이터를 관리한다.

import { atom } from 'recoil';

export const 데이터Atom = atom({
  key: 'key 지정',
  default: undefined, // 기본값 지정
})


_app.js

_app.js 에서 컴포넌트를 RecoilRoot 로 감싸 recoil 데이터를 전역으로 전달한다.

import { RecoilRoot } from 'recoil';

function App({ Component, pageProps }) {
  return (
    <RecoilRoot>
      <Component {...pageProps} />
    </RecoilRoot>
  )
}


useRecoilState

데이터를 호출 및 출력할 컴포넌트에서 useState() 가 아닌 useRecoilState() 로 state 를 생성해 데이터를 Recoil 에 보관한다.

redux 의 dispatch 하는 느낌.

import { useEffect } from 'react';
import { useRecoilState } from 'recoil';
import { 데이터Atom } from '../atoms';

export default function Page() {
  const [Items, setItems] = useRecoilState(데이터Atom);

  const fetchData = async ()=>{
    const data = await fetch(API_URL);
    const result = await data.json();
    setItems(result);
  }

  useEffect(()=>{
    fetchData();
  }, [])

  return (
    <main>
    </main>
  );
}


useRecoilValue

단순히 저장된 데이터를 불러오기만 한다면 useRecoilValue() 를 사용한다.

import { useRecoilValue } from 'recoil';
import { 데이터Atom } from '../atoms';

export default function Page() {
  const Items = useRecoilValue(데이터Atom);

  return (
    <main>
    </main>
  );
}


useSetRecoilState

상태 데이터를 읽어오지 않고 업데이트만 하려고 할때 사용한다.


useResetRecoilState

상태를 초기화한다.

atom 선언 시 설정했던 default 값으로 되돌린다.


selector

selector는 atom 또는 selector 를 참조해서 새로운 값을 return 하는 순수함수이다.

참조하는 atom 이 업데이트 되면 따라서 업데이트 된다.

atom 에는 최소한의 값만 저장하고 이로부터 유도된 값을 selector 로 관리하는 것이 좋다.


API 호출 함수를 순수함수 형태로 분리해서 관리할 수 있다.

먼저 API 호출을 위한 api.js 파일을 생성한다.

import { selectorFamily } from 'recoil';

export const get데이터 = selectorFamily({
  key: 'key',
  get: () => async () => {
    const data = await fetch(API_URL);
    const result = await data.json();
    return result;
  },
})


커스텀 hook 을 생성해 API 데이터를 atom 객체에 적용한다.

setData.js 파일을 components 폴더에 생성한 후 SetData() 함수를 만들어 데이터를 atom 객체에 저장했다.

import { useEffect } from 'react';
import { 데이터Atom } from '../atoms';
import { get데이터 } from '../api';
import { useRecoilState, useRecoilValue } from 'recoil';

export default function setData() {
  const setItems = useSetRecoilState(데이터Atom);
  const result = useRecoilValue(get데이터());

  useEffect(()=>{
    setItems(result);
  }, []);

  return null;
}


호출할 컴포넌트에서 Suspense 를 이용해 SetData 컴포넌트가 데이터를 불러올때까지 기다렸다가 아래 코드를 실행하도록(컴포넌트를 마운트 시키도록) 동기화 처리한다.

<React.Suspense fallback={<p>loading...</p>}>
  <SetData />
</React.Suspense>
<출력컴포넌트>