리액트에서 컴포넌트의 렌더링을 발생시킬 수 있는 방법에는 useEffect
와 state
가 대표적이라고 생각한다. 그 중 state
는 단어 그대로 상태이며, 변경이 발생한 즉시 해당 state가 포함된 컴포넌트를 재실행한다.
따라서 state가 만약 props
를 통해 여러 컴포넌트에 퍼져있다면 해당 state가 변경될때마다 state를 갖고 있는 모든 컴포넌트는 재렌더링될 것이다.
실제로 state가 전역적으로 관리되어야 하는 경우가 꽤 있는데, 대표적인 예시가 라이트/다크 모드다. 다만 전역적으로 사용되어야 하는 state가 실제로 필요한 컴포넌트까지 전달되도록 불필요하게 여러 컴포넌트를 통해 전달되는 경우가 꽤 많다. 이러다보면 drilling
이슈가 발생할 수 있어 context API나 Recoil 방식을 사용하여 전역적인 state를 관리할 수 있다.
추후 다른 글에서도 다룰 예정이라 간단하게만 짚고 넘어가려 한다. 전역적인 상태 context
를 contextProvider
를 사용하여 배포한다고 생각하면 된다. 하지만 provider를 해당 컴포넌트에 감싸줘야 하므로 결국 실제로 해당 context를 사용하지 않는 중간 컴포넌트까지 재렌더링되는 이슈는 동일하게 발생한다.
React 개발팀에서 만든 새로운 상태 관리 시스템이다. 전역적으로 관리해야하는 state를 하나의 bubble(atom
)으로 갖고 있고, 해당 state를 필요로 하는 컴포넌트에서 그 값을 직접 갖다 쓰는 방식이다!
당연히 중간 단계의 컴포넌트가 불필요하게 state를 전달받을 필요가 없어 재렌더링 이슈가 없고, 사용법이 간단한 장점이 있다.
npm install Recoil
을 통해 프로젝트에 설치해준다.
index.tsx
에서 <App />
컴포넌트를 <RecoilRoot>
로 감싸주기만 한다면 Recoil을 사용하기 위한 준비는 모두 끝났다.
atoms.tsx
등 아톰을 관리할 수 있는 파일 내에 아톰을 생성한다.
문법은 다음과 같다.
const today = new Date();
export const dateState = atom<Date>({
key: "date",
default: today,
});
key값으로 atom을 구분하고, 기본값으로 어떤 요소를 사용할지 전달하면 된다. 위 코드는 ts환경이어 atom 뒤에 <Date>
를 통해 자료형까지 명시해주었다.
atom은 단순히 특정 state(값)을 건네준다고 생각하면 된다.
useRecoilValue
: 컴포넌트 내부에서 사용하고자 하는 아톰 값을 가져올 때 사용useRecoilState
: 컴포넌트 내부에서 사용하고자 하는 아톰 값과 값을 변경할 수 있는 함수를 배열 형태로 가져올 때 사용 (useState 문법과 비슷하다)useSetRecoilState
: 컴포넌트 내부에서 특정 아톰 값을 변경하고자 할 때 사용Selectors
A selector represents a piece of derived state. You can think of derived state as the output of passing state to a pure function that derives a new value from the said state.
Selector는 atom을 가져다가 원하는대로 가공한 결과를 반환(get)하거나 atom을 수정하는(set) 역할을 수행한다.
공식문서에서 코드와 설명을 가져왔다.
function selector<T>({
key: string,
get: ({
get: GetRecoilValue,
getCallback: GetCallback,
}) => T | Promise<T> | Loadable<T> | WrappedValue<T> | RecoilValue<T>,
set?: (
{
get: GetRecoilValue,
set: SetRecoilState,
reset: ResetRecoilState,
},
newValue: T | DefaultValue,
) => void,
dangerouslyAllowMutability?: boolean,
cachePolicy_UNSTABLE?: CachePolicy,
})
key
: selector 구분용 문자열get
: derived state
를 리턴하는 함수. 직접 값을 리턴할 수도 있고, 비동기적인 Promise
, 동일한 자료형의 다른 아톰이나 selector를 리턴할 수도 있다. get()
: atom 값을 가져올 때 사용하는 함수set
: writeable state를 리턴하는 함수.get()
: atom 값을 가져올 때 사용하는 함수set()
: atom 값을 수정할 때 사용하는 함수reset()
: recoil state값을 초기값으로 변경할 때 사용하는 함수