[리액트] useRecoilValueLoadable() 알아보고 사용하기

코린·2023년 2월 6일
0

리액트

목록 보기
10/22
post-thumbnail

앞선 게시글 내용이 Suspense 였죠? 이것은 오늘 설명할 이 친구를 위한 빌드업..이었습미닥!!!!

우선 얘를 알게 된 이유는 말이죠... 제가 이제 랭킹페이지를 무한스크롤로 구현해야 했는데 새롭게 데이터를 불러오려고 할 때 전체화면이 로딩이 되더란 말이죠.. 그걸 해결하기 위해서 오늘 이 친구를 공부해보겠습니닥!


신나게 렛츄꼬

 
.
.
.

 

Recoil 넌 몬데..?

Recoil은 새로 등장한 상태 관리 라이브러리입니다.

제가 사용해 본 결과 Redux 보다 간편하게 사용할 수 있다는 점이 장점이었습니다. Redux는 훌륭한 상태 관리 라이브러리이지만 기본적인 store 구성을 위해 많은 보일러 플레이트와 장황한 코드를 작성해야 한다는...그런 점이 있습니다. (저에게는 단점입니다.)

하지만 디버깅 측면에 있어서는 Recoil은 제공하는 안정적인 Devtool이 없기 때문에 Redux가 더 우수합니다. 필요에 따라서 적절히 골라서 사용하는 것이... 좋을 것 같습니다..! 근데 전 암튼... Recoil이 더 정감이 가는..그런 상황~

Recoill을 사용하면 atoms(공유 상태)에서 selectors (순수 함수)를 거쳐 React 컴포넌트로 내려가는 data-flow를 만들 수 있습니다.

Atoms

Atoms는 상태의 단위이며, 업데이트와 구독이 가능합니다.

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

위 코드처럼 atom 함수를 이용해서 구현합니다.

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

function FontButton() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  return (
    <button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
      Click to Enlarge
    </button>
  );
}

버튼을 클릭하면 fontSize의 값이 1만큼 증가합니다. fontSizeState atom을 사용하는 다른 컴포넌트의 글꼴 크기도 함께 변화합니다. 저는 이거를 이해할 때 전역 변수와? 같은 느낌으로 이해했습니다.

function Text() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  return <p style={{fontSize}}>This text will increase in size too.</p>;
}

Selectors

Selector는 atoms나 다른 selectors를 입력으로 받아들이는 순수 함수(pure function)입니다. 상위의 atoms 또는 selectors가 업데이트되면 하위의 selector 함수도 다시 실행됩니다. 컴포넌트들은 selectors를 atoms처럼 구독할 수 있으며 selectors가 변경되면 컴포넌트들도 다시 렌더링됩니다.

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

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

get 속성은 계산될 함수입니다. get 인자를 통해서 atoms와 다른 selectors에 접근할 수 있습니다. 위 코드에서도 get을 이용해 fontSizeState atom 값을 이용하고 있습니다.

다른 atoms나 selectors에 접근하면 자동으로 종속 관계가 생성됩니다. 참조했던 다른 atoms나 selectors가 업데이트되면 이 함수도 다시 실행됩니다. 위 코드의 경우 fontSizeState가 변화하게 되면 함수가 다시 실행되게 됩니다.

이 Selecotr는 useRecoilValue()를 사용하여 읽을 수 있습니다. useRecoilValue()는 하나의 atom이나 selector를 인자로 받아 대응하는 값을 반환합니다.

function FontButton() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  const fontSizeLabel = useRecoilValue(fontSizeLabelState);

  return (
    <>
      <div>Current font size: ${fontSizeLabel}</div>

      <button onClick={setFontSize(fontSize + 1)} style={{fontSize}}>
        Click to Enlarge
      </button>
    </>
  );
}

그래서 useRecoilValueLoadable이 몬덱..?

이 친구는 React Suspense를 사용하지 않은 비동기 쿼리를 가능하게 해줍니다.

보류중인 비동기 selector를 다루기 위해서 React Suspense를 사용하지 않고도 이 훅을 이용하여 렌더링 중 상태를 확인할 수 있습니다.

function UserInfo({userID}) {
  const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID));
  switch (userNameLoadable.state) {
    case 'hasValue':
      return <div>{userNameLoadable.contents}</div>;
    case 'loading':
      return <div>Loading...</div>;
    case 'hasError':
      throw userNameLoadable.contents;
  }
}

상태는 총 3가지로 나뉩니다.

hasValue, loading, hasError입니다.

이 세가지 상태를 활용하면 Suspense와 동일하게 구현할 수 있게 됩니다. hasvalue면 해당 컨텐츠를 불러오고 loading일 경우에는 로딩페이지를 불러오고 hasError일 경우에는 에러처리를 하도록 구현하면 됩니다.

출처

Recoil 주요 개념

Recoil useRecoilValueLoadable

profile
안녕하세요 코린입니다!

0개의 댓글