keepPreviousData (v4) / placeholderData: prev => prev (v5) giữ data trang trước khi paginate — tránh flash trắng; kết hợp với prefetch trang tiếp theo cho UX hoàn hảo. keepPreviousData là v3/v4 API, trong v5 thay bằng placeholderData: (previousData) => previousData (identity function).
- Khi queryKey thay đổi (page 1 → page 2), thay vì show loading + clear data cũ, React Query giữ nguyên data của page 1 trong khi fetch page 2 —
isPlaceholderData: truecho biết đang hiển thị data cũ. - UX impact lớn với pagination: user thấy page 1 vẫn hiển thị (có thể mờ đi để indicate loading), page 2 load xong thì replace — không có flash trắng.
- Kết hợp với prefetch để UX hoàn hảo:
useEffect(() => { if (!isPlaceholderData && hasNextPage) { queryClient.prefetchQuery({ queryKey: ['todos', page + 1], queryFn: () => fetchTodos(page + 1) }) } }, [data, page, isPlaceholderData, queryClient]). - Cũng hữu ích với filter/search: khi user gõ query search, giữ previous results trong khi tìm kiếm mới → không flash empty.
Pitfall: nếu dùng select transform, previousData cũng đã qua select — types match đúng.