본문 바로가기
Javascript/react

React Recoil 사용하기

by Redking

소개

Recoil은 component의 state를 더 쉽게 관리하기 위해 페이스북에서 제작한 react state 관리 라이브러리다. react 자체에 이미 state 관리 기능이 내장되어 있지만 보완해야할 점이 있어 Recoil이 만들어 졌다.

react의 한계 https://recoiljs.org/ko/docs/introduction/motivation

- component의 state는 공통된 element까지 끌어올림으로써 공유될 수 있지만, 이 과정에서 거대한 트리가 다시 렌더링되는 효과를 야기하기도 한다.
- Context는 단일 값만 저장할 수 있으며, 자체 소비자(consumer)를 가지는 여러 값들의 집합을 담을 수는 없다.
- 이 두가지 특성이 트리의 최상단(state가 존재하는 곳)부터 트리의 잎(state가 사용되는 곳)까지의 코드 분할을 어렵게한다.

Recoil은 API가 단순하게 되어있고 hook과 비슷한 점이 많다. Recoil을 사용하기 위해서는 최상위 React 트리를 감싸야 하고 state는 atom단위로 선언하여 모든 useState를 Recoil에 내장되어 있는 useRecoilState로 대체해야 한다.

 

react의 내부 상태만 활용하고 아주 작은 단위의 atom 단위로 관리되고 selector라는 순수 함수를 제공합니다. 상태가 변경되면 atom을 참조하는 componnet만 리랜더링 되고 recoil의 상태들은 상호 의존성을 가지고 있기 때문에 여러 상태를 가진 컴포넌트들을 유기적으로 관리 가능

 

Atom

atom은 state라고 볼 수 있다. component구독할 수 있는 React state라고 생각하면 된다. atom의 값을 변경하면 변경한 atom을 구독하고 있는 component들이 모두 다시 렌더링된다. atom을 생성하기 위해 어플리케이션에서 고유한 키 값과 디폴트 값을 설정해야한다. 디폴트 값은 정적인 값, 함수가 될 수 있다.

export const userNameState = atom({
  key: 'userNameState',
  default: 'redk'
});

useRecoilState — atom의 값을 구독하여 업데이트할 수 있는 hook. useState와 동일한 방식으로 사용할 수 있다.

useRecoilValue — setter 함수 없이 atom의 값을 반환만 한다.

useSetRecoilState — setter 함수만 반환한다.

setter 함수는 [name, setName]이 있는 경우 2번째 인자를 의미합니다.
import {userNameState} from './atoms'
// useRecoilState
const NameInput = () => {
  const [name, setName] = useRecoilState(userNameState);
  const onChange = (event) => {
   setName(event.target.value);
  };
  return <>
   <input type="text" value={name} onChange={onChange} />
   <div>Name: {name}</div>
  </>;
}
// useRecoilValue
const SomeOtherComponentWithName = () => {
  const name = useRecoilValue(userNameState);
  return <div>{name}</div>;
}
// useSetRecoilState  
const SomeOtherComponentThatSetsName = () => {
  const setName = useSetRecoilState(userNameState);
  return <button onClick={() => setName('rulaa')}>Set Name</button>;
}

Selectors

getter와 setter를 직접 정의해서 사용할 수 있는 순수 함수이며 이를 활용하려면 상태를 읽고 쓸 때 데이터를 가공하거나 유효성 검사와 같은 기능을 추가 가능합니다. 이 셀렉터 내부에서 다른 atom이나 다른 selector를 참조할 수 있고 이를 구독한다고 표현합니다. 이렇게 될 경우 다른 데이터들에 대해서 의존성을 갖게 되는데 이 구독하고 있는 상태가 외부에서 변경 되면 이selector는 이를 감지하고 재평가 하여 컴포넌트를 다시 랜더링 해주게 됩니다. 

 

selector는 getter는 필수지만 setter는 선택사항입니다. 읽기, 쓰기 모두 가능한 hook을 이용할때 발생하는 오류를 방지하기 위해 구분해서 써야한다. 네이밍도 이를 따라서 읽기 전용인 getter만 있는 함수는 LeadOnly같은 네이밍을 추가

import { atom, selector } from "recoil";

const firstName = atom<string>({
  key: "firstName",
  default: "",
});
const secondName = atom<string>({
  key: "secondName",
  default: "",
});

const atomNameReadOnly = selector<string>({
  key: "atomName",
  get: ({ get }) => {
    const firstName = get(firstName);
    const secondName = get(secondName);
    return `${secondName} ${firstName}`;
  },
});

'Javascript > react' 카테고리의 다른 글

react 클래스 컴포넌트의 super  (0) 2022.05.02
react 클래스 컴포넌트의 this  (0) 2022.05.02
React에서 Axios 사용하기  (0) 2022.04.06
React 컴포넌트 라이브러리 Top 11  (0) 2021.06.02
React Fragments  (0) 2021.04.02

댓글