본문 바로가기
React/Recoil

[Recoil] Recoil 맛보기

by Rayched 2024. 11. 6.
목차
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 Component에서 만든 state를 PushBtn과 cDisplay에 props 통해서 전달한다,

 

최상위 컴포넌트인 App에서 선언한 'Counter'라는 state에 버튼 클릭 횟수를 기억해 두고

이를 필요로 하는 <PushBtn /><Display /> 컴포넌트에 props를 통해 전달을 한다.

 

아직은 [App - {PushBtn, Display}] 식의 단순한 형태라 큰 문제가 없어 보인다.

 

하지만 이런 식으로 React App 전체에 영향을 주는 공통 state를 props를 통해

상위에서 하위로 전달하는 방식은 별로 좋은 방식이 아니다.

 

A, state를 props 통해 E Component에게 전달하는 과정

 

위와 같은 구조를 가진 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로 업데이트를 해보도록 하겠다.

 

디자인은 그대로, BtnCount State를 직접적으로 사용 가능

 

버튼 클릭 예제 링크 (CodeSandbox)

 

이전 예제에서 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>를 호출해 주자.

RecoilRoot를 불러오지 않고, 그대로 Recoil State를 사용하면 발생하는 Error Message

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