카테고리 없음

[Recoil] React를 위한 상태관리 라이브러리(atom, Hooks)

제로콜라먹는사람 2022. 1. 29. 02:43
반응형

Recoil이란?

페이스북에서 내놓은 새로운 상태관리 라이브러리이다.

페이스북 리액트 코리아 그룹의 한 포스트에는 이러한 장점이 있다고 말해주었다.

 

1. atom/selector라는 단위를 통해서 derived state(파생 상태)를 효과적으로 처리하고 상태의 "코드 분할"이 가능해진다.

2. 기존 상태관리 라이브러리(ex. MobX, Redux) 보다 훨씬 단순한 API를 제공한다.

3. 페이스북 내부적으로 몇몇 프로젝트에서 사용되고 있었고 이를 라이브러리화 한 것이다.

 

즉 어플리케이션에서 상태관리를 하기 위한 라이브러리중 하나이다.

공식문서를 통해 학습을 진행해 보았고 이를 정리하기 위해 포스팅을 하였다.

 

 

Recoil 시작하기 | Recoil

React 애플리케이션 생성하기

recoiljs.org

Recoil API

atom(options)

  • atom은 Recoil의 state를 표현한다. atom()함수는 쓰기 가능한 RecoilState 라는 객체를 반환한다.
  • atom은 고유한 key와 default 값을 설정해야 한다.
  • atom 값은 불변으로 초기에 세팅되어있다.
const textState = atom({
  key: 'textState', // 어플리케이션 전체에서 고유한 ID 값이다.
  default: "" // atom의 초깃값 또는 Promise 또는 동일한 값을 나타내는 다른 atom이나 selector

  effects_UNSTABLE?: $ReadOnlyArray<AtomEffect<T>>, atom을 위한 선택적인 Atom Effects 배열이다. (잘모르겠다..)
  dangerouslyAllowMutability?: boolean, // Recoil은 atom의 상태변화에 의존한다. 즉 함부로 바꿀수 없도록 boolean값을 통해서 설정하는 부분이다.
})

atom과 함께 쓰이는 Hooks

  • useRecoilState() : atom 읽기, 쓰기
  • useRecoilValue() : 읽기전용
  • useSetRecoilState() : 쓰기전용
  • useResetRecoilState() : 초기화

useRecoilState(state)

  • React Hook의 useState와 비슷하게 동작한다.
  • 읽기와 쓰기가 모두 가능하다.
  • 즉 상태의 value와 상태를 업데이트하는 함수인 tuple을 리턴해준다.useRecoilValue(state)
const textState = atom({key: 'textState', default: []});
const [text, setText] = useRecoilState(textState);

useRecoilValue(state)

  • atom읽기전용상태
  • selector읽기, 쓰기 둘다 가능이다.
  • useState가 없는대신 Redux에서 subscribe처럼 구독상태 이다.
  • 구동상태: 상태가 업데이트되면 리렌더링을 한다. (항상 주시하고있다고 추상적으로 이해)
    const text = useRecoilValue(textState);

useSetRecoilState(state)

  • 읽기전용에서 쓰기 를 추가하고 싶을 때 사용된다.
  • useRecoilState의 두번째 반환값인 함수라고 생각할 수 있다.
  • 이 경우에도 update를 구독하고 리렌더링 한다.
    const setText = useSetRecoilValue(textState);
    console.log(text)
    // 123

    const newState = 123;
    setText((oldState) => [...oldState, newState])
    console.log(text)
    // 123123

useRsetRecoilState(state)

  • 상태를 default값으로 리셋할 때 사용한다.
  • RecoilState 객체를 넣어준다.
  • 이것도 결국 함수처럼 사용한다.
    const setText = useSetRecoilValue(textState);
    console.log(text)
    // 123

    const resetText = useResetRecoilState(textState);
    resetText();

    // default value

예시코드 종합

import {
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
  useSetRecoilState,
  useResetRecoilState,
} from "recoil";

const textState = atom({
  key: "textState",
  default: [],
});

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

  const value = useRecoilValue(textState);

  let newValue = "10";
  const setValue = useSetRecoilState(textState);

  const resetText = useResetRecoilState(textState);

  console.log(text, value);

  return (
    <div>
      <h2>
        State: {text} Value: {value}
      </h2>
      <input
        onChange={(e) => {
          setText(e.target.value);
        }}
      />
      <button
        onClick={() => {
          setValue((oldState) => [...oldState, newValue]);
        }}
      >
        setValue
      </button>
      <button
        onClick={() => {
          resetText();
        }}
      >
        resetValue
      </button>
    </div>
  );
}

문제점, 고민

useSetRecoilState를 button의 onClick함수에서 호출하지않고 component 내부에서 호출하니 무한 재귀호출이 발생하였다.

요약

atom

  • atom은 RecoilState라는 객체를 반환한다.
  • RecoilState는 key 값과 Prototype만을 가지고 있다.
  • atom은 각종 Recoil의 Hooks와 함께 사용된다.

즉 아래의 Hook들은 결국 atom을 읽느냐(상태의 값) 쓰느냐(상태의값을 업데이트하는 함수)로 구분할 수 있었다.

  • useRecoilState(state): 읽기, 쓰기
  • useSetRecoilState(state): 읽기전용
  • useRecoilState(state) : 쓰기전용
  • useResetRecoilState(state) : 초기화

selector : 내일해야징... 눈이 침침

반응형