상태관리 라이브러리 - Recoil

lyshine·2023년 7월 20일
0

React

목록 보기
4/6

개요

상태관리 라이브러리로 Redux는 단반향의 흐름 상태로 디버깅하기 쉽지만 action, reducer, selector, store를 초기에 세팅하는 것은 번거롭고 많은 boilerplate 코드가 필요하다. 그래서 Redux-toolkit라이브러리도 나오게 되어 좀 더 간단해졌지만 초기세팅은 여전히 번거롭다.

Recoil

React를 위한 상태관리 라이브러리

Redux와 Mobx 등의 상태관리 라이브러리들은 리액트 내부 라이브러리가 아니다. 따라서 리액트의 가상돔 내부 로직과는 별개로 작동했다.

But!, 리코일은 React를 위해 동작하는 상태관리 라이브러리이다.

API, 의미, 동작을 최대한 “리액트스럽게” 유지하며 이를 개선하고자 한다.

  • hook처럼 리액트의 상태를 간단하게 변경하고 이용 가능하다.

  • Recoil을 사용하면 atoms(상태)에서 selectors(순수함수)를 거쳐 React 컴포넌트로 내려가는 데이터흐름 그래프를 만들 수 있다.

  • 데이터 플로우 그래프를 통해 상태를 매핑하는 방법과 파생된 상태를 리액트 컴포넌트에 제공한다.

Atoms

컴포넌트가 구독할 수 있는 상태의 단위

  • 업데이트와 구독이 가능
  • atom 업데이트시 구독된 각각의 컴포넌트는 새로운 값을 반영하여 재렌더링된다.
  • 동일한 atom이 여러 컴포넌트에서 사용되는 경우 모든 컴포넌트는 상태를 공유한다.
  • Atom 생성 : atom
// atom 함수 사용해 생성
const fontSizeState = atom({
  key: 'fontSizeState', //고유한 키값 필요
  default: 14, //기본 상태값
});
  • atom 사용하기 : useRecoilState
function FontButton() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  return (
    <button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
      Click to Enlarge
    </button>
  );
}

여기서 fontSizeState atom을 사용하는 다른 컴포넌트의 글꼴 크기도 같이 변화하게 된다.

Selectors

Recoil에서 함수나 파생된 상태를 나타낸다.

  • atoms 상태값을 동기 또는 비동기 방식을 통해 변환한다.
  • atoms나 다른 selectors를 입력으로 받아들이는 순수 함수
  • 상위의 atoms나 selectors가 업데이트되면 하위의 selector 함수도 다시 실행
  • 컴포넌트는 selectors를 구독하고 selectors가 변경되면 컴포넌트들도 재렌더링
  • 최소한의 상태집합만 atoms에 저장하고 파생되는 데이터들은 selectors에서 계산하여 쓸모없는 상태의 보전을 방지할 수 있다.
  • get 함수만 제공되면 Selector는 읽기만 가능한 RecoilValueReadOnly 객체를 반환하고,
    set 함수 또한 제공되면 Selector는 쓰기 가능한 RecoilState 객체를 반환함
  • Selectors 생성 : selector 함수 사용
    • get (계산될 함수) : 전달되는 get 인자를 통해 atoms와 다른 selectors에 접근할 수 있다. ⇒ 자동으로 종속관계가 생성되어 참조한 것이 업데이트되면 이 함수도 다시 실행됨
    • set : 이 속성이 설정되면 selector는 쓰기 가능한 상태를 반환한다.
    • 아래 예시에서 보면, 이 selector는 fontSizeState라는 하나의 atom에 의존성을 갖는다
const fontSizeLabelState = selector({
  key: 'fontSizeLabelState',
  get: ({get}) => {
    const fontSize = get(fontSizeState);
    const unit = 'px';

    return `${fontSize}${unit}`;
  },
});
const transformSelector = selector({
  key: 'TransformSelector',
  get: ({get}) => get(myAtom) * 100,
  set: ({set}, newValue) =>
    set(myAtom, newValue instanceof DefaultValue ? newValue : newValue / 100),
});
  • writable하지 않을때는 useRecoilValue 사용
  • writable할때는 useRecoilState사용
  • useRecoilState(): 상태를 읽고 쓰려고 할 때 사용하고, 컴포넌트는 atom을 구독한다.
  • useRecoilValue(): 상태를 읽기만 할 때 사용하고, 마찬가지로 컴포넌트는 atom을 구독한다.
  • useSetRecoilState(): 상태를 쓰려고 할 때 사용한다. 구독하지 않는다.
  • useResetRecoilState(): 초기화 함수 제공. atom선언시 넘겼던 default값으로 초기화한다. 구독하지 않는다.

0개의 댓글