
페이스북이 만든 상태관리 라이브러리 Recoil
리액트의 상태 관리를 하는 방법은 여러 가지가 있지만,
새로 다뤄야 하는 Recoil에 대해 공부한 내용을 기록한다.
공식문서: Recoil을 사용하면 atoms (공유 상태)에서 selectors (순수 함수)를 거쳐 React 컴포넌트로 내려가는 data-flow graph를 만들 수 있다.
Atoms는 컴포넌트가 구독할 수 있는 상태의 단위다.
Selectors는 atoms 상태값을 동기 또는 비동기 방식을 통해 변환한다.
redux와 비교해보면, Atoms는 store, Selectors는 action 함수인가? 🤔
npm install recoil
recoil 상태를 사용하는 컴포넌트는 부모 트리 어딘가에 나타나는 RecoilRoot 가 필요하다.
루트 컴포넌트가 RecoilRoot를 넣기에 가장 좋은 장소다.
import React from 'react';
import {
RecoilRoot,
atom,
selector,
useRecoilState,
useRecoilValue,
} from 'recoil';
function App() {
return (
<RecoilRoot>
<CharacterCounter />
</RecoilRoot>
);
}
상태 정의하기
atom이 업데이트되면 각각의 구독된 컴포넌트는 새로운 값을 반영하여 다시 렌더링 된다. atom이 여러 컴포넌트에서 사용되는 경우 모든 컴포넌트는 상태를 공유한다.atom 함수를 사용해 생성
atom함수에key와default로 기본값 설정
key는 고유해야 하며default 초기값은 비워도 된다const fontSizeState = atom({
key: 'fontSizeState',
default: 14,
});
// 또는
const fontState = atom({
key: 'fontState',
default: {
idx: 0,
name: 'subTitle',
size: 18,
color: 'blue'
}
});
atom 호출atom을 읽고 쓰려면
useRecoilState라는 훅을 사용.
useState와 비슷하지만 상태가 컴포넌트 간에 공유될 수 있다는 차이가 있다.
import { atom } form 'recoil';
function FontButton() {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
return (
<button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
Click to Enlarge
</button>
);
}
// 버튼을 클릭하면 버튼의 글꼴 크기가 1만큼 증가하며,
// fontSizeState atom을 사용하는 다른 컴포넌트의 글꼴 크기도 같이 변화한다.
function Text() {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
return <p style={{fontSize}}>This text will increase in size too.</p>;
}
getter와 setter를 직접 정의해서 사용할 수 있는 순수함수.
Selector

컴포넌트의 관점에서 보면
selectors와atoms는 동일한 인터페이스를 가지므로 서로 대체할 수 있다.
Selectors 생성Selectors는
selector함수를 사용해 정의
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
get: ({get}) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});
Recoil에서는 특이하게 읽기 전용 함수와 쓰기 전용 함수를 제공한다.
Selectors는 useRecoilValue()를 사용해 읽을 수 있다useRecoilValue 읽기 전용 함수 예제function FontButton() {
const [fontSize, setFontSize] = useRecoilState(fontSizeState);
const fontSizeLabel = useRecoilValue(fontSizeLabelState);
return (
<>
<div>Current font size: ${fontSizeLabel}</div>
<button onClick={setFontSize(fontSize + 1)} style={{fontSize}}>
Click to Enlarge
</button>
</>
);
}
useSetRecoilState 쓰기 전용 함수 예제
reference 학습할 때 좀 더 공부해보자..😅
const setList = useSetRecoilState(productsState);
Recoil에서는 reset 함수를 추가로 제공한다.
// ... 생략
const resetProducts = useResetRecoilState(productsState);
useEffect(() => {
return () => resetProducts(); // 언마운트 될 때 초기화
}, []);