> ## Documentation Index
> Fetch the complete documentation index at: https://inertiajs-vi.tuantq.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Gộp props

<Warning>Bạn đang xem tài liệu Inertia.js v2. Inertia.js v3 đã được phát hành và hiện là phiên bản mặc định. Hãy xem [hướng dẫn nâng cấp](/v3/getting-started/upgrade-guide) để bắt đầu.</Warning>

Inertia ghi đè các prop cùng tên khi tải lại một trang. Tuy nhiên, trong một số trường hợp bạn cần gộp dữ liệu mới với dữ liệu hiện có, chẳng hạn khi triển khai nút "tải thêm" cho kết quả phân trang. Component [Infinite scroll](/v2/data-props/infinite-scroll) sử dụng cơ chế gộp prop ở bên dưới.

Việc gộp prop chỉ hoạt động trong [partial reload](/v2/data-props/partial-reloads). Các lần truy cập tải đầy đủ trang luôn thay thế toàn bộ prop, kể cả khi bạn đã đánh dấu chúng để gộp.

## Các phương thức gộp

Để gộp một prop thay vì ghi đè, bạn có thể dùng phương thức `Inertia::merge()` khi trả response.

```php theme={null}
Route::get('/items', function () {
    // Static array of tags...
    $allTags = [
        'Laravel', 'React', 'Vue', 'Tailwind', 'Inertia',
        'PHP', 'JavaScript', 'TypeScript', 'Docker', 'Vite',
    ];

    // Get chunk of tags by page...
    $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),
    ]);
});
```

Phương thức `Inertia::merge()` sẽ nối các phần tử mới vào cuối mảng hiện có ở cấp root. Bạn có thể đổi hành vi này để chèn các phần tử vào đầu mảng.

```php theme={null}
// Append at root level (default)...
Inertia::merge($items);

// Prepend at root level...
Inertia::merge($items)->prepend();
```

Để kiểm soát chính xác hơn, bạn có thể chỉ định các thuộc tính lồng nhau cụ thể cần gộp trong khi phần còn lại của object vẫn được thay thế.

```php theme={null}
// Only append to the 'data' array, replace everything else...
Inertia::merge(User::paginate())->append('data');

// Prepend to the 'messages' array...
Inertia::merge($chatData)->prepend('messages');
```

Bạn có thể kết hợp nhiều thao tác và nhắm đến nhiều thuộc tính cùng lúc.

```php theme={null}
Inertia::merge($forumData)
    ->append('posts')
    ->prepend('announcements');

// Target multiple properties...
Inertia::merge($dashboardData)
    ->append(['notifications', 'activities']);
```

Ở phía client, Inertia tự động xử lý toàn bộ quá trình gộp theo cấu hình phía máy chủ của bạn.

## Khớp các phần tử

Khi gộp mảng, bạn có thể dùng tham số `matchOn` để khớp các phần tử hiện có theo một field cụ thể và cập nhật chúng thay vì nối thêm phần tử mới.

```php theme={null}
// Match posts by ID, update existing ones...
Inertia::merge($postData)->append('data', matchOn: 'id');

// Multiple properties with different match fields...
Inertia::merge($complexData)->append([
    'users.data' => 'id',
    'messages' => 'uuid',
]);
```

Trong ví dụ đầu tiên, Inertia sẽ duyệt mảng `data` và cố gắng khớp từng phần tử theo field `id`. Nếu tìm thấy phần tử khớp, phần tử hiện có sẽ được thay thế. Nếu không tìm thấy, phần tử mới sẽ được nối vào cuối.

## Deep merge

Thay vì chỉ định những path lồng nhau cần gộp, bạn có thể dùng `Inertia::deepMerge()` để thực hiện deep merge cho toàn bộ cấu trúc.

```php theme={null}
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()` được giới thiệu trước khi `Inertia::merge()` hỗ trợ prepend và nhắm đến các path lồng nhau. Trong hầu hết trường hợp, `Inertia::merge()` cùng các phương thức append và prepend là đủ.

## Visit phía client

Bạn cũng có thể gộp prop trực tiếp ở phía client mà không cần gửi request đến server bằng [client-side visits](/v2/the-basics/manual-visits#client-side-visits). Inertia cung cấp các [prop helper](/v2/the-basics/manual-visits#prop-helpers) để append, prepend hoặc thay thế giá trị prop.

## Kết hợp với deferred props

Bạn có thể kết hợp [deferred props](/v2/data-props/deferred-props) với các prop có thể gộp để trì hoãn việc tải prop và đánh dấu prop đó là có thể gộp sau khi được tải xong.

```php theme={null}
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(),
    ]);
});
```

## Kết hợp với Once Props

Bạn có thể nối modifier `once()` vào merge prop để đảm bảo dữ liệu chỉ được resolve một lần và được phía client ghi nhớ qua các lần điều hướng tiếp theo.

```php theme={null}
return Inertia::render('Users/Index', [
    'activity' => Inertia::merge(fn () => $user->recentActivity())->once(),
]);
```

Để biết thêm về once props, xem tài liệu [once props](/v2/data-props/once-props).

## Reset props

Ở phía client, bạn có thể cho server biết rằng mình muốn reset một prop. Điều này hữu ích khi cần xóa giá trị prop trước khi gộp dữ liệu mới, chẳng hạn khi người dùng nhập truy vấn tìm kiếm mới trên một danh sách phân trang.

Tùy chọn request `reset` nhận một mảng chứa các key của prop mà bạn muốn reset.

```js theme={null}
router.reload({
    reset: ['results'],
    // ...
})
```

***

## Tài liệu chính thức

Bài dịch này được đối chiếu từ [tài liệu Inertia.js v2 chính thức](https://inertiajs.com/docs/v2/data-props/merging-props). Nếu có khác biệt do phiên bản hoặc cập nhật mới, hãy ưu tiên tài liệu chính thức làm nguồn tham chiếu.
