【Next.js 13】Client Componentで`use`フックを使う
タイミーでフロントエンドエンジニアをしているnisshi-です。
今回はNext.js 13のクライアントコンポーネントにおいて、use
フックを利用する基本的な流れを紹介したいと思います。
Server Componentとuseフック
Next.js 13において、コンポーネントはサーバー側でレンダリングされるサーバーコンポーネントがデファクトになりました。
一方、
先日Reactに追加されたuse
フックは、再レンダリングが走らないサーバーコンポーネントでは特に意識せずに利用する事が出来ますが
import { use } from 'react'
async function getTodoList() {
// https://jsonplaceholder.typicode.com/
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
const result = await response.json();
return result;
}
export default function TodoListPage() {
const todos = use(getTodoList());
return (
<table>
{/* ...省略... */}
<tbody>
{todos.map((todo) => (
<tr key={todo.id}>
<td>{todo.userId}</td>
<td>{todo.id}</td>
<td>{todo.title}</td>
</tr>
))}
</tbody>
</table>
)
}
クライアントコンポーネントで下記の様にuse
フックを使うと無限レンダリングが発生します。
+ 'use client'
import { use } from 'react'
async function getTodoList() {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
const result = await response.json();
return result;
}
export default function TodoListPage() {
const todos = use(getTodoList());
// ↓!無限にレンダリングされる!
return (
<table>
{/* ...省略... */}
<tbody>
{todos.map((todo) => (
<tr key={todo.id}>
<td>{todo.userId}</td>
<td>{todo.id}</td>
<td>{todo.title}</td>
</tr>
))}
</tbody>
</table>
)
}
何故このような事が起こるのか
use
フック自体には、SWR
やTan Stack Query
の様にキャッシュの責務が無い為、再レンダリングが発生しうるクライアントコンポーネント上ではPromise解決 -> レンダリング -> Promise解決.....
というループに陥るためです。
このあたりは@uhyo様が詳しくまとめられているので、そちらの記事も併せてご確認頂ければ幸いです。
どうすれば良いか
use
と同じく、先日Reactに追加されたcache
を利用します。
import { cache } from 'react'
const getTodoList = cache(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
const result = await response.json();
return result;
});
fetcherとなる関数をcache
で包めば、戻り値がメモ化され、呼び出し側のコンポーネントの再レンダリングが抑止されます。
cache
の詳細に関しては↓をご覧ください。
最後に
以上がuse
とcache
を利用する基本的な流れになります。
サーバーコンポーネントがデファクトになっているNext 13ですが、実務においてはクライアントコンポーネントとサーバーコンポーネントのコラボレートが発生しうるケースは多いと考えています(例 : ユーザー入力をトリガーにしたインクリメンタル検索等)
use
やcache
を適切に使い、ReactとNext.jsのアップデートを引き続き最大限楽しみましょう。
また、タイミーではフロントエンド始め、エンジニアを積極的募集中でした。
もしご興味を持って頂けましたら、是非一度下記をご確認頂けますと幸いでした。
それではまた別の記事で。
Discussion