Cache của infinite query không phải một mảng phẳng mà là object { pages, pageParams } — pages là mảng các response, pageParams là mảng tham số dùng để lấy từng trang. invalidateQueries sẽ fetch lại tuần tự tất cả các trang đang có, người dùng cuộn sâu 10 trang thì đó là 10 request.
Ghi trực tiếp bằng setQueryData, giữ nguyên cấu trúc:
qc.setQueryData(['feed'], (old) => {
if (!old) return old
return {
...old,
pages: old.pages.map((page) => ({
...page,
items: page.items.map((it) => (it.id === updated.id ? updated : it)),
})),
}
})Lưu ý khi triển khai:
- Phải trả về object mới cho cả pages và page chứa item, nếu mutate tại chỗ thì component không re-render.
- Với thao tác thêm/xoá item, ghi cache thủ công sẽ làm lệch phân trang (item bị đẩy sang trang sau, trùng hoặc mất khi tải trang tiếp). An toàn hơn là invalidate, hoặc dùng phân trang theo cursor thay vì offset để chèn/xoá không đổi ranh giới trang.
- Khi chỉ cần làm mới trang đầu, refetchPage/tuỳ chọn giới hạn số trang refetch tránh được việc quét lại toàn bộ.