We want to hear from you!Take our 2020 Community Survey!

Concurrent 모드 API 참고서 (실험 단계)

주의

이 페이지는 안정된 배포판에서는 아직 사용할 수 없는 실험적인 기능들에 관해 설명합니다. 프로덕션용 앱에선 React의 실험 배포판을 사용하지 마세요. 이 기능들은 React의 일부가 되기 전에 경고 없이 크게 변경될 수 있습니다.

이 문서는 얼리어답터들과 궁금해하시는 분들을 위해 제작된 문서입니다. React를 처음 접해본다면 이러한 기능들을 걱정하지 않아도 됩니다. 그 기능들을 바로 배울 필요는 없습니다.

이 페이지는 React Concurrent 모드에 대한 API 참고서입니다. 도입부에 대한 가이드를 찾고 있다면, Concurrent UI 패턴을 확인해주세요.

주의: 이는 커뮤니티 프리뷰이며 최종적으로 안정된 배포판이 아닙니다. 향후에 이 API는 변경될 수도 있습니다. 본인의 책임하에 사용하세요!

Concurrent 모드 활성화

createRoot

ReactDOM.createRoot(rootNode).render(<App />);

ReactDOM.render(<App />, rootNode)을 대체하고 Concurrent 모드를 활성화합니다.

Concurrent 모드에 대한 더 자세한 설명이 필요하다면, Concurrent Mode 문서를 참고해주세요.

createBlockingRoot

ReactDOM.createBlockingRoot(rootNode).render(<App />)

ReactDOM.render(<App />, rootNode)를 대체하고 Blocking 모드를 활성화합니다.

Concurrent 모드를 선택하면 React 작동하는 방식에 의미적 변화가 생깁니다. 이는 몇몇 컴포넌트에서 Concurrent 모드를 사용할 수 없다는 걸 의미하며 몇몇 앱은 곧바로 Concurrent 모드로 마이그레이션을 할 수 없습니다.

Blocking 모드는 Concurrent 모드의 일부만 포함하며 곧바로 마이그레이션 할 수 없는 앱의 중간 마이그레이션 단계로 사용됩니다.

Suspense API

Suspense

<Suspense fallback={<h1>Loading...</h1>}>
  <ProfilePhoto />
  <ProfileDetails />
</Suspense>

Suspense는 컴포넌트가 렌더링되기 전에 무언가를 “기다릴 수 있도록 하며”, 기다리는 동안에 폴백을 보여줍니다.

위 예시에서 ProfileDetails는 일부 데이터를 가져 오기 위해 비동기 API 호출을 기다리고 있습니다. ProfileDetailsProfilePhoto를 기다리는 동안에 Loading... 폴백을 대신 보여줍니다. <Suspense>의 모든 자식이 로드될 때까지 폴백을 계속 표시한다는 점에 주의해주세요.

Suspense는 두 개의 props를 사용합니다.

  • fallback은 로딩 표시기를 받아들입니다. 폴백은 Suspense 컴포넌트의 모든 자식이 렌더링을 마치기 전까지 표시됩니다.
  • unstable_avoidThisFallback은 boolean을 받아들입니다. 초기 로드할 때 이 경계를 보여주는 걸 건너뛸 지 말 지 React에게 알려줍니다. 향후 배포판에서 이 API는 제거될 수 있습니다.

<SuspenseList>

<SuspenseList revealOrder="forwards">
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={1} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={2} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={3} />
  </Suspense>
  ...
</SuspenseList>

SuspenseList는 컴포넌트가 사용자에게 표시되는 순서를 조정하여 일시 중단 할 수 있는 많은 컴포넌트를 조정하는 데 도움을 줍니다.

여러 컴포넌트가 데이터를 가져올 때 예상하지 못한 순서로 데이터가 도착할 수 있습니다. SuspenseList로 이러한 항목을 감싸면, React는 이전 항목을 표시하기 전까지 목록에 있는 항목을 출력하지 않습니다. (이 동작은 수정할 수 있습니다)

SuspenseList은 두 개의 props를 사용합니다.

  • revealOrder(forwards, backwards, together)SuspenseList 자식이 표시되는 순서를 정의합니다.

    • together는 하나씩 표시하지 않고 준비됐을 때 모두 한번에 표시합니다.
  • tail (collapsed, hidden)SuspenseList에서 로드되지 않은 항목을 표시하는 방법을 나타냅니다.

    • 기본적으로, SuspenseList는 목록에 있는 모든 폴백을 표시합니다.
    • collapsed는 목록에서 다음 폴백만 표시합니다.
    • hidden은 로드되지 않은 항목을 표시하지 않습니다.

SuspenseListSuspenseList 컴포넌트 아래에 있고 가장 인접한 SuspenseSuspenseList 컴포넌트에만 동작한다는 점에 주의해주세요. 한 단계보다 깊은 경계는 검색하지 않지만 여러 SuspenseList 컴포넌트를 중첩해 그리드를 형성할 수는 있습니다.

useTransition

const SUSPENSE_CONFIG = { timeoutMs: 2000 };

const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);

useTransition다음 화면으로 transition하기 전에 컨텐츠가 로드 될 때까지 대기함으로써 컴포넌트가 바람직하지 않은 로딩 상태를 피할 수 있게 해줍니다. 또한 컴포넌트가 더 중요한 업데이트를 즉시 렌더링 할 수 있도록 후속 렌더링까지 느린 데이터 가져오기를 지연시킬 수 있습니다.

useTransition hook은 배열에서 두 개의 값을 반환합니다.

  • startTransition은 callback을 받는 함수입니다. React에게 지연하고자 하는 상태를 말해주기 위해 이 함수를 사용할 수 있습니다.
  • isPending은 boolean입니다. transition이 완료되기를 기다리고 있는지 알려주는 React의 방식입니다.

일부 상태 업데이트로 컴포넌트가 중단되면 해당 상태 업데이트는 transition으로 감싸져야 합니다.

const SUSPENSE_CONFIG = { timeoutMs: 2000 };

function App() {
  const [resource, setResource] = useState(initialResource);
  const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
  return (
    <>
      <button
        disabled={isPending}
        onClick={() => {
          startTransition(() => {
            const nextUserId = getNextId(resource.userId);
            setResource(fetchProfileData(nextUserId));
          });
        }}
      >
        Next
      </button>
      {isPending ? " Loading..." : null}
      <Suspense fallback={<Spinner />}>
        <ProfilePage resource={resource} />
      </Suspense>
    </>
  );
}

위 코드에서 데이터 조회를 startTransition으로 감쌌습니다. 이를 통해 다음 프로필 페이지의 렌더링과 연관된 Spinner를 2초동안(timeoutMS에 표시된 시간) 지연시키면서 프로필 데이터를 바로 가져올 수 있습니다.

isPending boolean은 React에게 컴포넌트가 transition 중이라는 걸 알리기 때문에, 이전 프로필 페이지에 로딩 텍스트를 표시하여 사용자에게 알려줍니다.

Transition에 대한 자세한 내용은 Concurrent UI 패턴를 참고해주세요.

useTransition Config

const SUSPENSE_CONFIG = { timeoutMs: 2000 };

useTransitiontimeoutMS가 포함된 선택적인 Suspense Config를 허용합니다. 이 시간초과(밀리 초 내에 일어나는)는 다음 상태(위의 예시에서 새로운 프로필 페이지)를 표시하기 전에 기다리는 시간을 React에게 알려줍니다.

주의: 여러 모듈 간에 Suspense Config를 공유하는 것이 좋습니다.

useDeferredValue

const deferredValue = useDeferredValue(value, { timeoutMs: 2000 });

최대 timeoutMS 동안 “뒤처질 수 있는” 값의 지연된 버전을 반환하세요.

이는 흔히 사용자 입력을 기반으로 즉시 렌더링하거나 데이터 조회를 기다려야 할 때 인터페이스를 반응적으로 유지하는 데에 사용합니다.

이에 대한 좋은 예시는 텍스트 입력입니다.

function App() {
  const [text, setText] = useState("hello");
  const deferredText = useDeferredValue(text, { timeoutMs: 2000 });

  return (
    <div className="App">
      {/* input에 현재 텍스트를 계속 전달합니다. */}
      <input value={text} onChange={handleChange} />
      ...
      {/* 하지만 이 목록은 필요한 경우 "뒤처질" 수 있습니다. */}
      <MySlowList text={deferredText} />
    </div>
  );
 }

이를 통해 input에 대한 새로운 텍스트를 즉시 표시 할 수 있으므로 웹페이지가 반응적으로 느껴지도록 합니다. 한편, MySlowList는 업데이트 전에 timeoutMS에 따라 최대 2초 동안 “뒤처져서” 백그라운드에서 현재 텍스트로 렌더링 할 수 있습니다.

값의 지연에 대한 상세한 내용은 Concurrent UI 패턴을 참고해주세요.

useDeferredValue Config

const SUSPENSE_CONFIG = { timeoutMs: 2000 };

useDeferredValuetimeoutMS가 있는 선택적인 Suspense Config를 허용합니다. 이 시간초과(밀리초 내에 일어나는)는 뒤처진 값이 얼마나 지연될 수 있는지 React에게 알립니다.

React는 네트워크와 장치가 허용할 때 항상 더 짧은 지연을 사용하려고 합니다.

Is this page useful?Edit this page