[번역] Async rendering in React: Suspense, Hooks, and other methods_01

JJ·2023년 11월 16일

기술 블로그 번역

목록 보기
1/3

원문 링크

서론

모던 웹 어플리케이션에서 비동기 작업은 흔하게 일어난다. API를 통한 데이터 페칭, 컴포넌트를 로딩, 계산 작업을 실행하는 데 있어서 완료되기 까지 꽤 많은 시간이 소모된다. 리액트의 경우 특정 부분의 UI를 미리 렌더링하고 나머지 부분은 비동기적으로 처리하면서 성능을 향상시킨다.

리액트 버전 18에서 Suspense 라는 강력한 신 기능이 등장!

→ pending 상태에서 컴포넌트의 렌더링을 지연시키는 것.

리액트의 suspense가 어떻게 동작하는지 알아보기에 앞서, 함수형 컴포넌트에 대해서 이해해보자.

Understanding async React components

함수형 컴포넌트는 리액트 개발의 기초로, 자바스크립트 함수의 형태로 JSX를 반환한다. 함수형 컴포넌트는 간결하고, 테스트하기 쉬우며, Hooks의 도입으로 많은 인기를 얻었다.

리액트의 Suspense는 함수형 컴포넌트의 비동기화를 간단하게 처리할 수 있는 방법을 제공한다. Suspense를 사용하면, 데이터 페칭과 같은 비동기 작업이 완료되기 까지 특정 컴포넌트의 렌더링을 지연하는 것을 정의할 수 있다. 이를 통해 반응형 UI와 유저 경험을 원활하게 만들 수 있다.

함수형 컴포넌트에서, 데이터 페칭이나 다른 비동기 작업은 주로 useEffect Hook의 내부에서 이루어진다. 이 Hook의 문제점은 전체 컴포넌트 트리를 블럭하기 때문에 비동기 작업에 의존하지 않는 컴포넌트라 할지라도 블럭되게 된다.

리액트의 Suspense는 이러한 문제점을 간단한 방법으로 해결하여 함수형 컴포넌트를 비동기적으로 만든다. 비동기 작업이 완료되기 까지 지연시킬 컴포넌트를 정의하여, 반응형 UI와 사용자 경험을 향상시킬 수 있다.

Implementing React Suspense for async rendering

이제 비동기 렌더링을 위한 리액트 Suspense의 구현을 예제를 통해 알아보자.

우선, Suspense를 사용하기 위해 set up 해야할 부분이 있다. 이 과정에서는 suspense에 필요한 구성 요소와 지연시킬 컴포넌트를 suspense의 바운더리로 감싸주는 과정이 이루어진다.

<Suspense fallback={<Loading />}>
	<SomeComponent />
</Suspense>

Suspense 라는 component에는 다음과 같은 children 과 fallback props가 있다.

  • children
    • Suspense에서 지연시키고자 하는 컴포넌트에 해당되며, 지연되는 동안 fallback props에 해당하는 컴포넌트가 렌더링된다.
  • fallback
    • Suspense가 컴포넌트를 지연시키는 동안 보여줄 컴포넌트에 해당되며, 일반적으로 로딩 인디케이터나 스켈레톤 UI를 사용한다. Suspense는 컴포넌트 렌더링에 필요한 데이터가 완전하게 불러오기 전까지 fallback props를 렌더링 하며, 데이터가 완전하게 불러와지면, 자동으로 children props의 컴포넌트를 렌더링한다.

이제 기본 예제를 통해 Suspense의 사용법을 알아보자.

아래의 예제는 TV 프로그램 목록을 API 호출로 불러와서, 렌더링한다.

src/components/Shows/index.js

import { fetchShows } from "../fetchShows";
import * as Styles from "./styles";

const resource = fetchShows();

const formatScore = (number) => {
  return Math.round(number * 100);
};
const Shows = () => {
  const shows = resource.read();

  return (
    <Styles.Root>
      <Styles.Container>
        {shows.map((show, index) => (
          <Styles.ShowWrapper key={index}>
            <Styles.ImageWrapper>
              <img
                src={show.show.image ? show.show.image.original : ""}
                alt="Show Poster"
              />
            </Styles.ImageWrapper>
            <Styles.TextWrapper>
              <Styles.Title>{show.show.name}</Styles.Title>
              <Styles.Subtitle>
                Score: {formatScore(show.score)}
              </Styles.Subtitle>
              <Styles.Subtitle>Status: {show.show.status}</Styles.Subtitle>
              <Styles.Subtitle>
                Network: {show.show.network ? show.show.network.name : "N/A"}
              </Styles.Subtitle>
            </Styles.TextWrapper>
          </Styles.ShowWrapper>
        ))}
      </Styles.Container>
    </Styles.Root>
  );
};
export default Shows;
  • fetchShows 함수
    • resource object를 생성하는 함수
  • Shows 컴포넌트
    • resource.read() 메서드로 TV 프로그램 리스트를 불러와 shows 변수에 할당하고, 순회하여 각각의 TV 프로그램을 JSX로 보여준다.

src/App.js

import React, { Suspense } from "react";
import "./App.css";
import Shows from "./components/Shows";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1 className="App-title">React Suspense Demo</h1>
      </header>
      <Suspense fallback={<p>loading...</p>}>
        <Shows />
      </Suspense>
    </div>
  );
}
export default App;

앞서, Suspense 의 기본 사용방법처럼 Shows 컴포넌트가 Suspense 컴포넌트로 감싸져 있고, fallback props에 컴포넌트 대신, loading… 이 들어가 있다.

즉, Shows 컴포넌트에서 TV 프로그램 리스트가 페칭되기 전까지는 loading… 문구가 표시되고, 페칭이 완료되면 Shows 컴포넌트가 렌더링된다.

profile
한줄 한줄

0개의 댓글