본문 바로가기
React

Recoil 사용하기

by _sweep 2022. 3. 11.

Recoil 자습서를 읽고 작성한 글입니다.

 

✅ Recoil

Recoil은 React 상태 관리 라이브러리이다.

Recoil에서 상태 변화는 atoms(공유 상태)에서 selectors(순수 함수)를 거쳐 React 컴포넌트로 데이터가 흐른다.

여기서 atoms는 상태의 단위이고 Selectors는 atoms 상태 값을 동기 또는 비동기 방식으로 변환한다.

 

✔️ Atom

Atom은 Recoil에서의 상태 단위이다.

Atoms는 어떤 컴포넌트에서나 읽고 쓸 수 있으며 atom의 값을 읽는 컴포넌트들은 암묵적으로 atom을 구독한다.

Atom이 업데이트되면 이를 사용하고 있던 컴포넌트는 새로운 값을 반영해 재렌더링된다.

Atom은 런타임에서 생성될 수도 있으며 동일한 Atom이 여러 컴포넌트에서 사용되는 경우 모든 컴포넌트는 상태를 공유한다.

 

Atom은 atom() 함수를 사용해 생성한다.

 

const fontSizeState = atom({
  key: 'fontSizeState',
  default: 14,
});

 

key는 전역 상태의 이름을 의미하며 고유한 값을 가진다.

default는 전역 상태의 초기 상태를 지정한다.

 

컴포넌트에서 Atom을 읽고 쓰려면 useRecoilState라는 훅을 사용한다.

React의 useState과 비슷하지만 상태가 컴포넌트간 공유될 수 있다는 차이점이 존재한다.

 

const [state, setState] = useRecoilState(Atom);

 

✔️ Selectors

Selector는 atoms나 다른 selectors를 입력으로 받아들이는 순수함수이다.

상위의 atoms나 selectors가 업데이트되면 하위의 selector 함수도 다시 실행된다.

컴포넌트들은 atoms처럼 selectors를 구독할 수 있으며 selectors가 변경되면 컴포넌트들도 재렌더링된다.

 

Selector는 상태를 기반으로 하는 파생 데이터를 계산하는데 사용된다.

최소한의 상태 집합만 atoms에 저장하고 다른 파생 데이터들은 selectors에 명시한 함수를 통해 효율적으로 계산하며 쓸모없는 상태의 보존을 방지한다.

 

Selector는 어떤 컴포넌트가 자신을 필요로 하는지 또 자신은 어떤 상태에 의존하는지 추적하기 때문에 이러한 함수적 접근 방식을 매우 효율적으로 만든다.

 

Selector는 selector() 함수를 사용해 정의한다.

 

const fontSizeLabelState = selector({
  key: 'fontSizeLabelState',
  get: ({get}) => {
    const fontSize = get(fontSizeState);
    const unit = 'px';

    return `${fontSize}${unit}`;
  },
});

 

key는 Atom과 마찬가지로 이름을 뜻하며 고유한 값을 가진다.

get은 계산될 함수이다.

get 인자를 통해 atoms와 다른 selectors에 접근할 수 있으며 이러한 경우 종속 관계가 생성되므로 참조하는 atom이나 selector가 업데이트되면 이 함수도 다시 실행된다.

 

Selector는 useRecoilValue()를 사용해 읽을 수 있다.

 

const state = useRecoilValue(Selector);

 

Recoil 시작하기

✔️ 설치

먼저 Recoil을 사용하기 위해서는 Recoil을 설치해야 한다.

Recoil의 설치 명령어는 다음과 같다.

 

$ npm install recoil
$ yarn add recoil

 

✔️RecoilRoot

Recoil 상태를 사용하는 컴포넌트는 RecoilRoot가 필요하다.

보톤은 루트 컴포넌트를 RecoilRoot로 감싼다.

따라서 App.js에 적용한 경우 다음과 같다.

 

import React from 'react';
import {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
} from 'recoil';

function App() {
  return (
    <RecoilRoot>
      <CharacterCounter />
    </RecoilRoot>
  );
}

 

✔️ Atom과 Selector 사용

앞서 적었듯이 Atom은 atom()을,  Selector는 selector()를 사용해 선언한다.

그리고 각각 useRecoilState, useRecoilValue를 통해 값을 읽고 사용한다.

 

import React from 'react';
import {
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
} from 'recoil';

const textState = atom({
  key: 'textState', // unique ID (with respect to other atoms/selectors)
  default: '', // default value (aka initial value)
});

function CharacterCount() {
  const count = useRecoilValue(charCountState);

  return <>Character Count: {count}</>;
}

const charCountState = selector({
  key: 'charCountState', // unique ID (with respect to other atoms/selectors)
  get: ({get}) => {
    const text = get(textState);

    return text.length;
  },
});

function CharacterCounter() {
  return (
    <div>
      <TextInput />
      <CharacterCount />
    </div>
  );
}

function TextInput() {
  const [text, setText] = useRecoilState(textState);

  const onChange = (event) => {
    setText(event.target.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo: {text}
    </div>
  );
}

 

 

🔍 참조

recoil https://recoiljs.org/ko/docs/introduction/core-concepts

 

 

 

 

 

댓글