React에서 사용하는 Recoil은 상태 관리 라이브러리입니다. React 앱의 전역 상태를 관리하는데 사용되며, 컴포넌트 간에 데이터를 효율적으로 공유할 수 있게 해줍니다.
Recoil을 프로젝트에 설치하려면 다음과 같은 명령을 실행합니다.
bash
Copy code
npm install recoil
# 또는
yarn add recoil
앱의 최상위 컴포넌트에 RecoilRoot를 추가합니다. 이렇게 하면 Recoil 상태가 전체 앱에 공유됩니다.
import { RecoilRoot } from 'recoil';
function App() {
return (
<RecoilRoot>
<MyComponent />
</RecoilRoot>
);
}
export default App;
Atom은 상태의 기본 단위입니다. Atom을 만들고 내보낼 수 있습니다.
import { atom } from 'recoil';
export const textState = atom({
key: 'textState', // 고유한 ID
default: '', // 초기값
});
컴포넌트에서 Atom을 사용하려면 useRecoilState 훅을 사용합니다.
import { useRecoilState } from 'recoil';
import { textState } from './path/to/your/atoms';
function MyComponent() {
const [text, setText] = useRecoilState(textState);
return (
<div>
<input type="text" value={text} onChange={(e) => setText(e.target.value)} />
<p>{text}</p>
</div>
);
}
Selector를 사용하면 Atom에 기반한 계산된 상태를 생성할 수 있습니다.
import { selector } from 'recoil';
import { textState } from './path/to/your/atoms';
export const textLengthState = selector({
key: 'textLengthState',
get: ({ get }) => {
const text = get(textState);
return text.length;
},
});
👉🏻 이 함수는 다른 atom이나 selector의 값을 읽어 오기만 할 뿐, 값을 변경하지 않습니다.
여기서 읽은 값에 기반하여 계산된 값을 반환합니다.
컴포넌트에서 이 selector를 사용하려면 useRecoilValue 훅을 사용하면 됩니다.
import { useRecoilValue } from 'recoil';
import { textLengthState } from './path/to/your/selectors';
function MyComponent() {
const length = useRecoilValue(textLengthState);
return <p>Text length: {length}</p>;
}
selector는 상태를 파생하거나 변환하는 데 사용되며, 구성 객체(configuration object) 내에서 여러 속성을 정의할 수 있습니다. 다음은 일반적으로 selector 구성 객체에 추가할 수 있는 주요 속성들입니다.
key: selector의 고유 식별자입니다. 전체 애플리케이션 내에서 유일해야 하며, 디버깅과 지속성(persistence)에 사용됩니다.
get: 이 함수는 해당 selector의 값을 계산합니다. 필요한 다른 atom 및 selector의 값을 읽을 수 있으며, 읽은 값에 의존하는 파생 값을 반환
합니다.
set: 이 함수를 사용하면 selector의 값을 설정할 수 있으며, 다른 atom 및 selector의 값을 변경할 수도 있습니다.
이를 사용하여 읽기/쓰기 가능한 selector를 만들 수 있습니다.
cachePolicy_UNSTABLE: 이 속성을 사용하면 selector의 캐시 동작을 구성할 수 있습니다. 여기에는 캐시 크기 및 시간 제한과 같은 옵션이 포함될 수 있습니다.
예시:
import { atom, selector } from 'recoil';
const numberState = atom({
key: 'numberState',
default: 0,
});
const multipliedState = selector({
key: 'multipliedState',
get: ({ get }) => {
return get(numberState) * 2;
},
set: ({ set }, newValue) => {
set(numberState, newValue / 2);
},
});
이 훅을 사용하면 atom의 값을 읽고 쓸 수 있는 함수를 반환합니다.
import { useRecoilState } from 'recoil';
import { myAtom } from './atoms';
function MyComponent() {
const [value, setValue] = useRecoilState(myAtom);
// ...
}
이 훅을 사용하면 atom의 값을 설정할 수 있는 함수만 반환합니다. 현재 값은 필요하지 않은 경우에 유용합니다.
import { useSetRecoilState } from 'recoil';
import { myAtom } from './atoms';
function MyComponent() {
const setValue = useSetRecoilState(myAtom);
// ...
}
이 훅을 사용하면 atom의 값을 기본값으로 재설정할 수 있는 함수를 반환합니다.
import { useResetRecoilState } from 'recoil';
import { myAtom } from './atoms';
function MyComponent() {
const resetValue = useResetRecoilState(myAtom);
// ...
}
selector의 set 함수 내부에서도 atom의 값을 변경할 수 있습니다.
import { selector } from 'recoil';
export const mySelector = selector({
key: 'mySelector',
get: ({ get }) => {
// ...
},
set: ({ set }, newValue) => {
set(myAtom, newValue); // myAtom의 값을 변경
},
});
👉🏻 이러한 메서드를 사용하면 Recoil atom의 값을 효과적으로 관리하고 변경할 수 있으며, 해당 atom을 구독하는 컴포넌트는 atom의 값이 변경될 때 자동으로 다시 렌더링됩니다.
useSetRecoilState 훅은 atom 또는 읽기/쓰기 가능한 selector(read/write selector)에 사용될 수 있으며, 전달된 매개변수에 따라 동작이 달라집니다.
반환된 설정 함수를 사용하면 해당 atom의 값을 직접 변경할 수 있습니다.
const setMyAtomValue = useSetRecoilState(myAtom);
setMyAtomValue(newValue); // myAtom의 값을 직접 변경
반환된 설정 함수를 사용하면 해당 selector의 set 함수가 호출되며, set 함수 내부의 로직에 따라 atom의 값이 간접적으로 변경될 수 있습니다. 이를 통해 파생된 값이나 복잡한 상태 변경 로직을 구현할 수 있습니다.
const setMySelectorValue = useSetRecoilState(mySelector);
setMySelectorValue(derivedValue); // mySelector의 set 함수를 호출하여 atom의 값을 간접적으로 변경
👉🏻 이러한 접근 방식은 Recoil을 사용하여 상태 관리를 유연하고 표현력 있게 할 수 있게 해줍니다. Atom과 selector의 조합은 직접적인 상태 변경부터 복잡한 파생된 상태 로직까지 다양한 상황에서 활용할 수 있습니다.