React Recoil로 상태관리 방법
ReactrecoilatomselectorRecoilRootuseRecoilStateuseRecoilValueuseSetRecoilStateuseResetRecoilStateuseMemo
모듈 설치
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입니다.