🦧
Client ComponentsでSuspense+use使用時のエラー(Not implemented)の解決方法
環境
- react 18.2.0
- next 13.0.0
やっていたこと
Reactを17から18に、Next12から13にアップデートして、Client Componentsでfetchを含むコードを使用してcache + use + Suspenseなどを利用したところ、エラーが発生し、buildできなくなった。
結論
結論から言うと、SWRなどを使うか、Server Componentsにfetch系処理を移行して使う。
以下は、その経緯。
該当コード
PizzaList component
fetch api, cache + use
// PizzaList.tsx
const getPizza = cache(
(id: string): Promise<Pizza[]> =>
fetch(`${process.env.NEXT_PUBLIC_API_HOST}/pizza/${id}`).then((res) =>
res.json()
)
);
const PizzaList = () => {
const pizza = use(getPizza(id));
return (
<>
{pizza.map((p) => {
return (
<>
<div>{p.id}</div>
<div>{p.name}</div>
</>
);
})}
</>
);
};
export default PizzaList;
Pizza screen
dynamic import, Suspense
// pizza.tsx
'use client';
const PizzaList = React.lazy(() => import('@/components/pizza/PizzaList'));
const Pizza = () => {
return (
<Suspense fallback={<Loading />}>
<PizzaList />
</Suspense>
);
};
export default Pizza;
エラーログ
上記コードを動かすとエラーが発生した。
Uncaught Error: Not implemented.
at updateDehydratedSuspenseComponent (react-dom.development.js?160d:23538:1)
at updateSuspenseComponent (react-dom.development.js?160d:23235:1)
at beginWork (react-dom.development.js?160d:24544:1)
at beginWork$1 (react-dom.development.js?160d:31617:1)
at performUnitOfWork (react-dom.development.js?160d:30549:1)
at workLoopSync (react-dom.development.js?160d:30434:1)
at renderRootSync (react-dom.development.js?160d:30387:1)
at performConcurrentWorkOnRoot (react-dom.development.js?160d:29662:1)
at workLoop (index.js?82e4:10:3922)
at flushWork (index.js?82e4:10:3630)
at MessagePort.performWorkUntilDeadline (index.js?82e4:10:1812)
Example: fetch and use in Client Components
if you need to fetch data in a Client Component, we recommend using a third-party library
しばらくの間は、ClientComponentsで使う時はSWRなどを使用するのが良さそう。そう考えると、fetchは現時点ではSWRを使うか、ServerComponentsに入れてしまうのがベターだろう。
参考リンク
基本的にServerComponentsならasync/awaitで書いて、ClientComponentsはcache+useで書くというルール。
Discussion