use
React 19 推出了新的 API use
,可以用來取得非同步的內容或 Promise ,也可用來取得 Context。
use
只能在 render 期間使用,只能用在 Component 或 Hook 。需要注意的是 use
並不是 Hook,是可以在條件語句或迴圈使用的。
和 useContext
不同的是,use
可以在條件語句或迴圈使用。
function App({ show }) {
if (show) {
const theme = use(ThemeContext);
return <SomeComponent theme={theme} />;
}
return null;
}
use
取得 Promise當使用 use
取得 Promise 時,通常會搭配 Suspense 和 ErrorBoundary。
範例:
import { use, Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";
export default function App() {
const userPromise = db.connect.getUsers(id);
return (
<div>
<ErrorBoundary fallback={<ErrorFallback />}>
<Suspense fallback={<Loading />}>
<UserList userPromise={userPromise} />
</Suspense>
</ErrorBoundary>
</div>
);
}
"use client";
function UserList({ userPromise }) {
const users = use(userPromise);
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
透過以上寫法就不用使用 useState
和 useEffect
來處理資料狀態。
use
傳遞 Promise 注意事項通常會建議在 Server Components 中創建 Promise,並將 Promise 當作 props 傳遞給 Client Components ,並在 Client Component 中使用 use
。
如果要在 Server Component 取得資料,使用 async
和 await
就好,不需要使用 use
,以下是兩者的差別:
async
和 await
會在執行 await
時暫停渲染,直到 await
完成後會再繼續執行。use
會在取得資料後重新渲染元件。另外要注意的是不能在 render 的過程中創建的 Promise,應該使用已經創建好的 Promise。若在 render 中創建 Promise,會產生以下警告:
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
範例說明:
const fetchUserData = () => {
return fetch("https://example.com/users").then((res) => res.json());
};
const promiseFetchUserData = fetchUserData(); // 在外部創建 Promise
function UserList() {
const data = use(fetchUserData()); //這樣會出現錯誤
const data = use(promiseFetchUserData); // 正確用法
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
在使用 use
時也需要錯誤處理。use
無法直接在 try-catch
中使用,通常要配合 ErrorBoundary。除此之外,也可以在 Promise 的 catch 中提供替代值。
const userPromise = new Promise((resolve, reject) => {
reject();
}).catch(() => {
return "no user"; // 提供的替代值
});
在沒有處理錯誤時,React 會讓畫面直接崩潰。目前在 Function Component 沒有辦法建立 ErrorBoundary,需要使用 react-error-boundary 套件來處理錯誤,當錯誤發生時會顯示 fallback 的 UI 內容。
參考資料:
https://react.dev/blog/2024/04/25/react-19
https://react.dev/reference/react/use#usage
https://www.youtube.com/watch?v=AJOGzVygGcY
https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary