📌 개요
Recoil을 사용하면 atoms (공유 상태)에서 selectors (순수 함수)를 거쳐 React 컴포넌트로 내려가는 data-flow graph를 만들 수 있다. Atoms는 컴포넌트가 구독할 수 있는 상태의 단위다. Selectors는 atoms 상태값을 동기 또는 비동기 방식을 통해 변환한다.
아톰 (Atoms) | 셀렉터 (Selectors) |
공유 상태 (Shared State) | 순수 함수 (Pure Function) |
컴포넌트가 구독할 수 있는 상태 단위 | 아톰 상태 값을 동기 또는 비동기 방식으로 변환 |
📌 Atoms
Atoms는 상태의 단위이며, 업데이트와 구독이 가능하다. atom이 업데이트되면 각각의 구독된 컴포넌트는 새로운 값을 반영하여 다시 렌더링 된다. atoms는 런타임에서 생성될 수도 있다. Atoms는 React의 로컬 컴포넌트의 상태 대신 사용할 수 있다. 동일한 atom이 여러 컴포넌트에서 사용되는 경우 모든 컴포넌트는 상태를 공유한다.
간단한 예시로, 사용자의 로그인 상태를 저장하고 관리하는 Recoil atom을 만들어 보겠습니다.
const isLoggedInState = atom({
key: 'isLoggedInState',
default: false,
});
해당 atom을 컴포넌트에서 사용할 수 있습니다.
import { useRecoilState } from 'recoil';
function LoginPage() {
const [isLoggedIn, setIsLoggedIn] = useRecoilState(isLoggedInState);
const handleLogin = () => {
// 로그인 처리 로직
setIsLoggedIn(true);
}
return (
<div>
{isLoggedIn ? (
<p>로그인 되었습니다!</p>
) : (
<button onClick={handleLogin}>로그인</button>
)}
</div>
);
}
위 예시에서는, isLoggedInState atom을 useRecoilState hook을 사용해 컴포넌트 내부에서 사용하고 있습니다. 이를 통해 로그인 상태를 관리하고, 로그인 버튼을 누르면 setIsLoggedIn 함수를 통해 isLoggedIn 값을 변경하여 로그인 처리를 하고 있습니다.
📌 Selectors
- 셀렉터(Selector)는 상태 관리 라이브러리 중 하나인 Recoil에서 제공하는 개념으로, 파생된 상태를 생성하는 순수 함수입니다.
즉, 기존 상태나 다른 파생된 상태를 기반으로 새로운 상태를 계산하여 반환합니다. - 셀렉터는 아톰(Atom)이나 다른 셀렉터를 입력으로 받아들여 파생된 상태를 생성합니다. 또한, 상위의 아톰 또는 셀렉터가 업데이트 되면 하위의 셀렉터도 다시 실행됩니다. 이를 통해 최소한의 상태만 아톰에 저장하고 다른 모든 파생된 상태는 셀렉터를 통해 효과적으로 계산하여 불필요한 상태 보존을 방지합니다.
- 컴포넌트는 셀렉터를 아톰과 마찬가지로 구독할 수 있으며, 셀렉터가 변경되면 컴포넌트도 다시 렌더링 됩니다. 이를 통해 컴포넌트 관점에서 셀렉터와 아톰은 동일한 인터페이스를 가지므로 서로 대체 가능합니다.
- 셀렉터는 selector 함수를 사용해 정의하며, 식별을 위한 고유 key 설정이 필요합니다. get 메서드 내부에 사용되는 get 함수는 아톰 또는 다른 셀렉터를 전달 받을 수 있습니다. 다른 아톰, 셀렉터를 전달받으면 자동적으로 종속 관계가 생성되며 참조했던 다른 아톰, 셀렉터가 업데이트 되면 다시 실행됩니다.
- 셀렉터를 사용하면 함수적인 접근 방식을 매우 효율적으로 만들 수 있습니다. 즉, 어떤 컴포넌트가 필요로 하는지, 어떤 상태에 의존하는지 추적하므로, 최적화된 상태 관리가 가능해집니다.
간단한 예시로 Recoil의 selector 함수를 사용하여 fontSizeLabelState라는 셀렉터를 정의하는 코드입니다.
const fontSizeLabelState = selector({
key: 'fontSizeLabelState',
get: ({get}) => {
const fontSize = get(fontSizeState);
const unit = 'px';
return `${fontSize}${unit}`;
},
});
해당 셀렉터는 fontSizeState라는 아톰을 참조하고 있으며, get 메서드에서는 fontSizeState의 값을 가져와 px 단위로 된 문자열로 변환하여 반환합니다.
예를 들어, fontSizeState의 값이 16이라면, get 메서드는 16px 문자열을 반환하게 됩니다.
이렇게 selector 함수를 사용해 셀렉터를 정의하면, 다른 컴포넌트에서 해당 셀렉터를 구독하여 사용할 수 있습니다. 또한, fontSizeState 값이 변경되면 fontSizeLabelState의 값을 다시 계산하고, 구독 중인 컴포넌트에 변경 사항을 알리게 됩니다.
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>
</>
);
}
버튼를 클릭하면 버튼의 글꼴 크기가 증가하는 동시에 현재 글꼴 크기를 반영하도록 글꼴 크기 레이블을 업데이트하는 두 가지 작업이 수행됩니다.
참고사이트
https://recoiljs.org/ko/docs/introduction/core-concepts/#atoms
'React' 카테고리의 다른 글
[Next JS / React] Next JS에서 SVG 사용법 (0) | 2023.06.27 |
---|---|
Redux의 3원칙 (0) | 2023.04.06 |
Recoil 기본 개념 (1) | 2023.03.31 |
리액트 라우터 outlet 사용하여 중첩된 레이아웃 구성 (0) | 2023.03.09 |
Custom Hook 만들기 (0) | 2023.03.01 |