본문 바로가기

FrontEnd

리액트 use, 새로 등장한 훅을 알아보자 (React use)

반응형

최근 다수 유명 리액트 라이브러리 메인테이너들을 흥분시킨 RFC가 발표되었습니다.

https://github.com/reactjs/rfcs/pull/229

 

RFC: First class support for promises and async/await by acdlite · Pull Request #229 · reactjs/rfcs

Adds first class support for reading the result of a JavaScript Promise using Suspense: Introduces support for async/await in Server Components. Write Server Components using standard JavaScript a...

github.com

요약은 다음과 같습니다.

Suspense 사용 시, JavaScript Promise의 결과를 읽기 위한 일급 지원을 추가합니다.
  • 서버 컴포넌트의 async/await 지원을 도입합니다. 컴포넌트를 비동기 함수로 정의, 표준 JavaScript await 구문을 사용하여 서버 컴포넌트를 작성합니다.
  • Hook use를 도입합니다. await와 마찬가지로 use는 promise의 값을 unwrap하지만 클라이언트 측을 포함하여 일반 컴포넌트 및 Hook 내부에서 사용할 수 있습니다.
이를 통해 React 개발자는 안정적인 API를 통해 Suspense된 임의의 비동기 데이터 소스에 액세스할 수 있습니다.
RFC가 너무 길어서 나중을 위해 안읽고 있었지만, Bytes(https://bytes.dev/)에서 한페이지 요약을 해줬습니다.
Suspense는 아직 UI를 표시할 준비가 되지 않은(Pending) 컴포넌트 트리의 모든 부분에 대해
로딩 UI를 선언적으로 지정할 수 있는 React 컴포넌트 입니다.
이 RFC가 많은 주목을 받는 이유는 Suspense의 전체 목표에 한 걸음 더 다가갈 수 있기 때문입니다.
props나 state를 사용하는 것만큼 쉽게 네트워크를 통해 데이터를 읽는 것입니다.
 
동작 방식은 다음과 같습니다.

먼저 컴포넌트를 사용하는 위치를 파악합니다.

1. 서버일 경우 표준 async/await 구문을 사용하여 promise 기반 API**에 액세스할 수 있습니다.

* async 서버 컴포넌트의 제한 사항은 Hook을 사용할 수 없다는 것입니다.

async function Note({id, isEditing}) {
  const note = await db.posts.get(id);
  return (
    <div>
      <h1>{note.title}</h1>
      <section>{note.body}</section>
      {isEditing ? <NoteEditor note={note} /> : null}
    </div>
  );
}

2. 컴포넌트를 클라이언트에서 사용하는 경우 use hook***을 사용합니다.

* 다른 훅과 달리 use는 조건부로 사용하거나, 블록이나 루프 내에서 사용할 수 있습니다.

function Note({id, shouldIncludeAuthor}) {
  const note = use(fetchNote(id));

  let byline = null;
  if (shouldIncludeAuthor) {
    const author = use(fetchNoteAuthor(note.authorId));
    byline = <h2>{author.displayName}</h2>;
  }

  return (
    <div>
      <h1>{note.title}</h1>
      {byline}
      <section>{note.body}</section>
    </div>
  );
}​

use가 가져올 변화

리액트 코어 팀에 의하면,

  1. 조건부로 호출할 수 있는 유일한 Hook입니다.
  2. use(Something)을 일반적인 "래핑 해제" 작업으로 생각할 수 있습니다.
    • 현재는 프라미스만 해제하지만 앞으로는 use(Context) 및 다른 작업(예: use(Observable))도 허용할 계획입니다.
  3. 일부 외부 값의 래핑 해제만 수행하기 때문에(상태를 저장하지 않음) 조건부로 호출될 수 있습니다.
    • 다른 훅들처럼 렌더링 간 상태 유지, 비교와 같은 일을 하지 않는 단순함 때문이라는것 같군요
    • 리액트 렌더링 싸이클과 관련없는 데이터 읽기에 특화된 유틸리티 도구인 것 같습니다.

이게 뭐가 그리 대단한가?에 대해 감이 잘 안와서, 레딧 토론을 좀 살펴보았습니다.

https://www.reddit.com/r/reactjs/comments/y30uga/react_rfc_first_class_support_for_promises_and/

 

React RFC: First class support for promises and async/await

Posted in r/reactjs by u/acemarke • 94 points and 36 comments

www.reddit.com

리액트의 렌더링 멱등성 철학에 반하면서, 훅의 규칙에 혼자 반하는 예외를 사용하며,

안그래도 복잡해지고 있는 리액트 개발에 대한 우려와,

이제 CSR의 시대는 갔고 PESPA의 시대가 왔음을 인정해야 한다는 의견들도 있네요

 

현재로서는  서스펜스 생성과 결과 데이터를 읽는데,

대부분 외부 라이브러리 혹은 상용구에 의존하고 있습니다.

(현재는 Promise를 던지는 식의 귀찮은 구현을 직접 해야 합니다.)

 

이 훅이 생기면 렌더링 과정에서 use를 통해 비동기 함수를 호출할 수 있고

비동기 함수의 리턴 값을 suspense처럼 이미 로딩된 데이터로 가정하고 쓸 수 있다는 것이죠.

 

프론트엔드 개발 멘탈 모델이 점점 SSR 기반으로 옮겨가고 있는듯 합니다.

이는 피할 수 없는 흐름이겠죠?

반응형