分支
主 (6.23.1)開發人員
版本
6.23.1v4/5.xv3.x
等候
在此頁面

<Await>

用來渲染 延遲 值,並自動處理錯誤。務必檢閱 延遲資料指南,因為有幾個 API 會使用這個元件。

import { Await, useLoaderData } from "react-router-dom";

function Book() {
  const { book, reviews } = useLoaderData();
  return (
    <div>
      <h1>{book.title}</h1>
      <p>{book.description}</p>
      <React.Suspense fallback={<ReviewsSkeleton />}>
        <Await
          resolve={reviews}
          errorElement={
            <div>Could not load reviews 😬</div>
          }
          children={(resolvedReviews) => (
            <Reviews items={resolvedReviews} />
          )}
        />
      </React.Suspense>
    </div>
  );
}

注意: <Await> 預期會渲染在 <React.Suspense><React.SuspenseList> 父元件內,才能啟用備用 UI。

型別宣告

declare function Await(
  props: AwaitProps
): React.ReactElement;

interface AwaitProps {
  children: React.ReactNode | AwaitResolveRenderFunction;
  errorElement?: React.ReactNode;
  resolve: TrackedPromise | any;
}

interface AwaitResolveRenderFunction {
  (data: Awaited<any>): React.ReactElement;
}

children

可以是 React 元素或函式。

使用函式時,值會提供為唯一的參數。

<Await resolve={reviewsPromise}>
  {(resolvedReviews) => <Reviews items={resolvedReviews} />}
</Await>

使用 React 元素時,useAsyncValue 會提供資料

<Await resolve={reviewsPromise}>
  <Reviews />
</Await>;

function Reviews() {
  const resolvedReviews = useAsyncValue();
  return <div>{/* ... */}</div>;
}

errorElement

當 Promise 拒絕時,會渲染錯誤元素,而非 children。可以使用 useAsyncError 來存取錯誤。

如果 Promise 拒絕,您可以提供一個選擇性的 errorElement,以透過 useAsyncError hook 在內容 UI 中處理該錯誤。

<Await
  resolve={reviewsPromise}
  errorElement={<ReviewsError />}
>
  <Reviews />
</Await>;

function ReviewsError() {
  const error = useAsyncError();
  return <div>{error.message}</div>;
}

如果您未提供 errorElement,則拒絕的值會傳遞至最近的路由層級 errorElement,且可透過 useRouteError 勾子存取。

resolve

取得由 延遲 載入器傳回,即將解析並呈現的 Promise 值。

import {
  defer,
  Route,
  useLoaderData,
  Await,
} from "react-router-dom";

// given this route
<Route
  loader={async () => {
    let book = await getBook();
    let reviews = getReviews(); // not awaited
    return defer({
      book,
      reviews, // this is a promise
    });
  }}
  element={<Book />}
/>;

function Book() {
  const {
    book,
    reviews, // this is the same promise
  } = useLoaderData();
  return (
    <div>
      <h1>{book.title}</h1>
      <p>{book.description}</p>
      <React.Suspense fallback={<ReviewsSkeleton />}>
        <Await
          // and is the promise we pass to Await
          resolve={reviews}
        >
          <Reviews />
        </Await>
      </React.Suspense>
    </div>
  );
}