목차
1. Recoil
① Recoil 정의 및 설치 방법 (npm 기준)
② 상태 관리를 사용하는 이유
2. RecoilRoot
3. Atom
4. Recoil Hook
① useRecoilValue()
② useSetRecoilState()
③ useRecoilState()
1. Recoil
① Recoil 정의 및 설치 방법 (npm 기준)
Recoil은 React를 개발한 Meta 사에서 만든 상태 관리 라이브러리로
'atom'이라는 것을 통해서 React의 상태 (State)를 관리한다.
Recoil은 npm에 존재하는 라이브러리이기 때문에, 아래 명령어를 통해서 설치한다.
npm install recoil
② 상태 관리 (State Management)를 사용하는 이유
다음 장으로 넘어가기 전에 잠깐 React 프로젝트에서 상태 관리를 사용하는 이유에 대해 생각을 좀 해보자.
아래 예제는 버튼 하나와, 버튼을 클릭한 횟수를 보여주는 간단한 카운터(Counter) 예제이다.
위의 예제를 통해서 상태 관리 라이브러리 사용 전/후를 비교해보고자 한다.
먼저 Recoil 같은 상태 관리 라이브러리를 사용하지 않은 버전부터 확인해 보자.
See the Pen React - Button 예제 by Rayched (@Rayched) on CodePen.
최상위 컴포넌트인 App에서 선언한 'Counter'라는 state에 버튼 클릭 횟수를 기억해 두고
이를 필요로 하는 <PushBtn />과 <Display /> 컴포넌트에 props를 통해 전달을 한다.
아직은 [App - {PushBtn, Display}] 식의 단순한 형태라 큰 문제가 없어 보인다.
하지만 이런 식으로 React App 전체에 영향을 주는 공통 state를 props를 통해
상위에서 하위로 전달하는 방식은 별로 좋은 방식이 아니다.
위와 같은 구조를 가진 React App이 있고, 여기서 최상위 Component인
A에서 선언한 state가 최하위 컴포넌트인 E에게 필요한 상황이라고 가정해 보자.
A에서 선언한 state를 최하위 컴포넌트인 E에서 바로 사용을 할 수 없기 때문에
props 통해서 A - B - D - E 순으로 state를 전달받아야 한다.
B와 D 컴포넌트에서 해당 state를 사용하지 않더라도, A와 E 사이의 중간 다리로써
일일이 props를 통해서 state를 받고 이를 또 다음 하위 컴포넌트에게 전달해줘야 한다.
이때 React 컴포넌트에서 전역적으로 참조하는 상태를 전역 상태 (Global State)라고 하며
이를 관리하게 쉽게 해주는 것이 Redux, Zustand, Recoil과 같은 상태 관리 프로그램이다.
다시 처음의 버튼 예제로 돌아와서, 상태 관리 라이브러리인 Recoil을 이용해서
버튼 클릭 횟수를 나타내는 'Counter' state를 전역 state로 업데이트를 해보도록 하겠다.
이전 예제에서 PushBtn과 Display가 공통된 State, 'Counter'를 사용하기 위해서
상위 컴포넌트인 App에서 'Counter' State를 만들고
이를 props로 전달을 하는 식으로 전역 상태를 관리했었다.
하지만 이번 예제에서는 상태 관리 라이브러리인 Recoil을 도입했기 때문에
App에서 'Counter' State를 만들지 않고, 대신 'Counter'를 Recoil State로 만들고
PushBtn, Display 컴포넌트에서 'Counter'를 구독하는 형태로 사용하는데
이를 통해서 상위 컴포넌트에서 전역 상태를 만들고, props로 전달할 필요가 없어졌다.
이하의 과정을 통해서 Redux, Zustand, Recoil과 같은 상태 관리 라이브러리를 사용하면
기존의 State 전달을 위해 일일히 중간 다리를 거치지 않고, 필요한 컴포넌트에서 구독하는 형식으로
원하는 State를 바로 사용하는 것이 가능하다는 것을 알게 됐다.
이제 본격적으로 Recoil에 대해 맛을 보도록 하겠다.
2. RecoilRoot
기본적으로 Recoil State는 RecoilRoot 컴포넌트 내부에서 작동을 하는데
만약 Recoil State를 RecoilRoot 외부에서 사용할 경우 아래 사진과 같은 에러 메시지가 출력된다.
프로젝트 실행 중에 이런 메시지가 출력된다면, RecoilRoot를 import 하지 않았다는 것이므로
아래와 같이 App, index 같은 최상위 컴포넌트에서 <RecoilRoot>를 호출해 주자.
import { RecoilRoot } from "recoil";
function App(){
return (
<RecoilRoot>
<ToDoList />
</RecoilRoot>
);
}
3. Atom
Atom은 Recoil 상태 (State)의 단위이다.
'useRecoilValue()', 'useSetRecoilState()' Hook을 통해서 컴포넌트에서
해당 State를 사용(구독) 하거나, State의 값의 변경이 가능하다.
이때 다른 컴포넌트들이 Atom을 구독하고 있는 상태에서
Atom 값이 변경되면 이를 구독하는 모든 컴포넌트에서 Re-rendering이 발생한다.
Atom은 atom() 함수를 통해서 생성할 수 있으며, 인자로 객체 하나를 전달해줘야 한다.
이때 객체에는 해당 Atom만의 고유한 Key 값과 Default 값 (Atom의 초기 값), 두 가지를 전달한다.
const RecoilState = atom({
key: "AtomKey",
default: ""
});
이렇게 생성한 Atom은 Recoil Hook을 통해 컴포넌트에서 구독해서 사용할 수 있다.
4. Recoil Hook
① useRecoilValue()
인자로 전달한 Atom의 값(Value)을 컴포넌트에서 사용할 수 있게 해주는 Recoil Hook
Atom의 값을 불러오는 것만 가능하고, 값의 수정은 할 수 없다.
import {RecoilState} from "atom";
import {useRecoilValue} from "recoil";
const Values = useRecoilValue(RecoilState);
React 컴포넌트에서 Atom의 값을 단순히 읽는 기능만 필요한 경우
주로 사용되는 Recoil Hook이라고 보면 된다.
② useSetRecoilState()
인자로 전달한 Atom의 값을 변경하는 기능을 제공하는 Recoil Hook으로
State 값을 변경하는 setState() 함수를 return하는 함수이다.
import { RecoilState } from "atom";
import { useSetRecoilState } from "recoil";
const setValues = useSetRecoilState(RecoilState);
앞에서 다룬 useRecoilValue() 함수와는 다르게
Atom의 값을 변경하는 기능만 제공하는 Recoil Hook이다.
③ useRecoilState()
앞에서 설명한 useRecoilValue(), useSetRecoilState() Hook의 기능을 합친 함수로
React State를 생성할 때 사용했던 useState() Hook의 Recoil 버전이라고 보면 된다.
해당 함수는 Atom의 상태 값과 이를 수정할 수 있는 setState() 함수 return하며
이렇게 return하는 값은 배열 구조 분해 기법을 사용해서 Atom 변수와 setter 함수를 저장한다.
import { RecoilState } from "atom";
import { useRecoilState } from "recoil";
const [Values, setValues] = useRecoilState(RecoilState);
기본적인 형태와 사용법은 React의 useState() 함수와 동일하고
React Component에서 Atom의 값을 불러오고, 수정할 필요가 있을 때 사용한다.
📔 Reference
Recoil 공식 문서
'React > Recoil' 카테고리의 다른 글
[Recoil] Selector (0) | 2024.11.16 |
---|