본문 바로가기
개발일지/사이드프로젝트

[React-native]Context API, Recoil 어떤걸 쓸까? (feat. 렌더링)

by -제이리 2023. 4. 12.
728x90
320x100

react-native로 앱을 만들면서 전역으로 상태관리를 해야하는 상황이 필연적으로 찾아왔다.

 

Context API

처음에는 Context API를 사용해서 상태관리를 했었다. 하지만 변수값이 많아지면서 점점 렌더링이 느려지는 현상이 생겼다.

Provider에 제공한 value가 달라지면 Context API를 쓰고 있는 모든 컴포넌트가 리렌더링 된다는 것을 간과했었다.

Provider를 추가하더라도 Provider의 하위컴포넌트가 모두 렌더링되는 현상은 피할 수 가 없다.

(memoization을 통해 일부 문제를 해결할 수 있지만, 모든 것을 해결할 수 있는 방법은 아니며 한계가 있다고한다)

 

3번째 슬라이드에서 Context Provider를 추가한 후 하위의 모든 것이 다시 마운트된다.

성능에도 좋지 않을 뿐 아니라 Provider와 컴포넌트 트리 노드 사이에 강한 커플링이 생긴다.

 

낮은 빈도의 업데이트를 한다면 사용해도 별 문제가 없겠지만 업데이트가 자주 이뤄진다면 Context API는 정말 비효율적일 수 밖에 없다.  

Recoil

그래서 상태관리방법을 바꿔야했는데 많이 쓰이는 Redux를 쓸것이냐, 비교적 최근에 생긴 Recoil 쓸것이냐 고민했었다.

하지만 고민도 잠시, 보일러플레이트가 복잡한 Redux보단 예전에 간편하게 사용했던 경험이 있어서 Recoil로 사용하기로 했다.

 

Recoil은 페이스북에서 공식적으로 개발하고 있는 전역 상태관리 라이브러리다. 스토어 선언이 상당히 간편하고 간결하다.

Recoil을 시작하기 위해서는 어플리케이션을 RecoilRoot로 감싸고, 데이터를 atom이라는 단위로 선언하여 useState를 Recoil의 useRecoilState로 대체해야 한다.

 

 

 

Recoil은 변경된 Atom의 상태를 공유하고 있는 컴포넌트만 리렌더링된다. 그렇기 때문에 useContext에서처럼 구독하고 있는 모든컴포넌트 렌더링이 되는 현상을 피할 수 있다.

useContext에서 recoil로 전환한 결과 렌더링속도가 확연히 줄은것을 체감할 수 있었다. 

 

공식문서에 소개로 React스럽다고 나와있는데 정말 React스럽다. 그래서 Redux와 비교했을때 러닝커브도 낮은편이였다.

 

 

<주요기능>

  • Atom : atom은 하나의 상태의라고 볼 수 있다. 컴포넌트가 구독할 수 있는 React state라고 생각하면 된다. atom의 값을 변경하면 그것을 구독하고 있는 컴포넌트들이 모두 다시 렌더링된다. atom을 생성하기 위해 어플리케이션에서 고유한 키 값과 디폴트 값을 설정해야한다. 디폴트 값은 정적인 값, 함수 또는 심지어 비동기 함수(나중에 지원 예정)가 될 수 있다.
  • useRecoilState : atom의 값을 구독하여 업데이트할 수 있는 hook으로, useState와 동일한 방식으로 사용할 수 있다.
  • useRecoilValue : setter 함수 없이 atom의 값을 반환만 한다.
  • useSetRecoilState : setter 함수만 반환한다.
  • selector : seletor는 상태에서 파생된 데이터로, 다른 atom에 의존하는 동적인 데이터를 만들 수 있게 해준다. Recoil의 selector는 기존에 우리가 알던 selector의 개념과는 조금 다르다. Redux의 reselect와 MobX의 @computed처럼 동작하는 "get" 함수를 가지고 있다. 하지만 하나 이상의 atom을 업데이트 할 수 있는 "set" 함수를 옵션으로 받을 수 있다.

 

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>
  );
}

 

https://recoiljs.org/ko/

 

Recoil

A state management library for React.

recoiljs.org

 

마무리

렌더링 최적화를 위해 상태관리방식을 바꾸어줬을 뿐인데 확연하게 달라지니 신기하기도 하다. 이전 토이프로젝트를 만들때는 코드의 양도 많지 않다보니 Context API를 사용해도 별다른 문제점을 느끼지 못했었다. 그래서 이번 프로젝트에서도 사용하게 됐었는데 렌더링최적화를 하려고 문제점을 찾아보니 비효율적인 전역상태관리를 하고있었다. 왜 사람들이 redux를 쓰고 recoil을 사용하는지 알게 됐다.

 

 

728x90
320x100

댓글