<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>
);
}