Suspense

Yun·2024년 7월 12일
0

개인공부

목록 보기
23/28

< Suspense >

<Suspense>는 컴포넌트 렌더링을 지연시키고 대체 UI를 보여주는 기능이다. 비동기 작업을 처리할 때 유용하게 사용할 수 있으며, 주로 데이터 로딩이나 코드 스플리팅 같은 작업에 사용된다.

  • 로딩으로 인한 딜레이 중 사용자 경험을 개선할 수 있다. 빈 화면 대신 로딩 화면을 보여주며 사용자가 멈춤 현상을 경험하지 않게 한다.

  • 지연을 이용해 초기에 필요한 컴포넌트만 로드하여 초기 로딩 속도를 개선할 수 있다.

<Suspense fallback={<Loading />}>
  <SomeComponent />
</Suspense>
  • children : 렌더링하려는 실제 UI이다. children의 렌더링이 지연될 때, Suspense는 fallback을 대신 렌더링한다.

  • fallback : 대체 UI이다. children의 렌더링이 지연될 때 대신 렌더링되다가, 데이터가 준비됐을 때 children으로 다시 전환된다. 만약 fallback의 렌더링이 지연된다면 가장 가까운 부모 Suspense가 렌더링된다.

사용법

import { Suspense } from 'react';
import Albums from './Albums.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<Loading />}>
        <Albums artistId={artist.id} />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>Loading...</h2>;
}

위 코드는 앨범 데이터가 로딩되는 동안 Loading 컴포넌트를 표시한다. 로드가 끝났을 땐 Loading을 숨기고 다시 Albums 컴포넌트를 렌더링한다.

<Suspense fallback={<BigSpinner />}>
  <Biography />
  <Suspense fallback={<AlbumsGlimmer />}>
    <Panel>
      <Albums />
    </Panel>
  </Suspense>
</Suspense>

여러 Suspense를 중첩하여 로딩 순서를 만들 수도 있다.

  • Biography가 로드되지 않은 경우, BigSpinner가 표시된다.
  • Albums가 로드되지 않은 경우, AlbumsGlimmer가 표시된다.

useDeferredValue

  • useDefferredValue는 사용자가 빠르게 입력을 변경할 때, 결과가 즉시 업데이트되지 않고 약간 지연되도록 도와준다. 사용자 경험을 개선하고 불필요한 렌더링을 줄이는데 도움이 된다.

  • 지연 시간은 고정되어 있지 않으며, React에 여유가 있을 때 업데이트된다. 브라우저의 현재 상태나 작업 부하에 따라 달라질 수 있다.

useDeferredValue를 사용하면 쿼리의 지연된 버전을 아래로 전달할 수 있다.

import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';

export default function App() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;
  return (
    <>
      <label>
        Search albums:
        <input value={query} onChange={e => setQuery(e.target.value)} />
      </label>
      <Suspense fallback={<h2>Loading...</h2>}>
        <div style={{ opacity: isStale ? 0.5 : 1 }}>
          <SearchResults query={deferredQuery} />
        </div>
      </Suspense>
    </>
  );
}

위 예제는 검색 결과를 가져오는 동안 SearchResult가 지연되며, 지연되는 동안 이전 검색 결과를 계속해서 보여준다.

예를 들어 a를 검색하고 ab를 검색하면, ab의 결과를 가져오는 동안 a의 검색 결과를 투명도 50%로 보여준다.

lazy

lazy는 컴포넌트가 렌더링 될 때까지 로딩을 연기할 수 있다.

import { useState, Suspense, lazy } from 'react';
import Loading from './Loading.js';

const MarkdownPreview = lazy(() => delayForDemo(import('./MarkdownPreview.js')));

export default function MarkdownEditor() {
  const [showPreview, setShowPreview] = useState(false);
  const [markdown, setMarkdown] = useState('Hello, **world**!');
  return (
    <>
      <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} />
      <label>
        <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} />
        Show preview
      </label>
      
      {showPreview && (
        <Suspense fallback={<Loading />}>
          <h2>Preview</h2>
          <MarkdownPreview markdown={markdown} />
        </Suspense>
      )}
    </>
  );
}

위 예제는 checkbox가 체크되기 전까지 MarkdownPreview가 나타나지 않기 때문에, lazy를 이용해 지연시켰다.

참고

0개의 댓글

관련 채용 정보