Props のマージ
Inertia はページを再読み込みする際、同じ名前の props を上書きします。しかし、場合によっては既存のデータに新しいデータをマージしたいこともあります。たとえば、ページネーションされた結果に対して「さらに読み込む」ボタンを実装する場合です。Infinite scroll コンポーネントは、内部で prop マージを使用しています。
Prop のマージは 部分的なリロード のときのみ動作します。フルページ遷移では、マージ対象としてマークされていても、props は常に完全に置き換えられます。
マージ方法
上書きではなくマージしたい場合は、レスポンスを返す際に Inertia::merge() メソッドを使用できます。
Route::get('/items', function () {
// タグの静的配列...
$allTags = [
'Laravel', 'React', 'Vue', 'Tailwind', 'Inertia',
'PHP', 'JavaScript', 'TypeScript', 'Docker', 'Vite',
];
// ページごとにタグのチャンクを取得...
$page = request()->input('page', 1);
$perPage = 5;
$offset = ($page - 1) * $perPage;
$tags = array_slice($allTags, $offset, $perPage);
return Inertia::render('Tags/Index', [
'tags' => Inertia::merge($tags),
]);
});Inertia::merge() メソッドは、ルートレベルにある既存の配列に新しい要素を追加(append)します。この挙動は、代わりに先頭へ追加(prepend)するよう変更できます。
// ルートレベルで末尾に追加(デフォルト)...
Inertia::merge($items);
// ルートレベルで先頭に追加...
Inertia::merge($items)->prepend();より細かい制御が必要な場合は、オブジェクトの他の部分を置き換えつつ、特定のネストされたプロパティのみをマージ対象にできます。
// 'data' 配列のみに追加し、それ以外はすべて置き換える...
Inertia::merge(User::paginate())->append('data');
// 'messages' 配列の先頭に追加...
Inertia::merge($chatData)->prepend('messages');複数の操作を組み合わせたり、同時に複数のプロパティを対象にすることもできます。
Inertia::merge($forumData)
->append('posts')
->prepend('announcements');
// 複数のプロパティを対象にする...
Inertia::merge($dashboardData)
->append(['notifications', 'activities']);クライアント側では、サーバー側の設定に従って、Inertia がすべてのマージ処理を自動的に行います。
アイテムのマッチング
配列をマージする際、matchOn パラメータを使用すると、特定のフィールドで既存のアイテムと照合し、新しいアイテムを追加する代わりに更新できます。
// ID で投稿を照合し、既存のものを更新...
Inertia::merge($postData)->append('data', matchOn: 'id');
// 異なるマッチフィールドを持つ複数のプロパティ...
Inertia::merge($complexData)->append([
'users.data' => 'id',
'messages' => 'uuid',
]);最初の例では、Inertia は data 配列を反復処理し、各アイテムを id フィールドで照合しようとします。一致するものが見つかった場合、その既存アイテムは置き換えられます。一致しない場合は、新しいアイテムが追加されます。
ディープマージ
どのネストされたパスをマージするかを指定する代わりに、Inertia::deepMerge() を使用して構造全体をディープマージすることもできます。
Route::get('/chat', function () {
$chatData = [
'messages' => [
['id' => 4, 'text' => 'Hello there!', 'user' => 'Alice'],
['id' => 5, 'text' => 'How are you?', 'user' => 'Bob'],
],
'online' => 12,
];
return Inertia::render('Chat', [
'chat' => Inertia::deepMerge($chatData)->matchOn('messages.id'),
]);
});Inertia::deepMerge() は、Inertia::merge() に prepend やネストパスの指定がサポートされる前に導入されました。ほとんどの場合、append や prepend メソッドを備えた Inertia::merge() で十分です。
クライアントサイドの訪問
クライアントサイド訪問 を使用すれば、サーバーリクエストを行わずにクライアント側で直接 props をマージすることもできます。Inertia は、prop の値を追加・先頭追加・置き換えするための prop ヘルパーメソッド を提供しています。
Deferred Props との併用
Deferred props をマージ可能な props と組み合わせることで、prop の読み込みを遅延させ、読み込み完了後にマージ可能として扱うことができます。
Route::get('/users', function () {
$page = request()->input('page', 1);
$perPage = request()->input('per_page', 10);
return Inertia::render('Users/Index', [
'results' => Inertia::defer(fn() => User::paginate($perPage, page: $page))->deepMerge(),
]);
});Once Props との併用
マージ prop に once() 修飾子をチェーンすることで、データが一度だけ解決され、その後のナビゲーション間でクライアントに記憶されるようにできます。
return Inertia::render('Users/Index', [
'activity' => Inertia::merge(fn () => $user->recentActivity())->once(),
]);once props の詳細については、once props のドキュメントを参照してください。
Props のリセット
クライアント側から、prop をリセットしたいことをサーバーに伝えることができます。これは、ページネーションされたリストでユーザーが新しい検索クエリを入力した際など、新しいデータをマージする前に prop の値をクリアしたい場合に便利です。
reset リクエストオプションには、リセットしたい prop のキーの配列を指定します。
router.reload({
reset: ['results'],
// ...
})