T
TanStack2y ago
fair-rose

Initial data is applied when the query key is changed

This all works well until I change the query key and then it goes back to the initial data until I fetch the new data.
export const usePostInfiniteQuery = (
postIds: number[],
initialData?: NewPublicPosts[],
) => {

return useInfiniteQuery({
queryKey: ["fetchPosts", postIds],
queryFn: ({ pageParam }) => fetchPosts(postIds, pageParam),

getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
if (!lastPage) {
return null;
}

if (lastPage.length < 10) return null;

return lastPageParam + 10;
},

initialPageParam: 0,

retry: 0,
enabled: false,

placeholderData: (previousData, previousQuery) => previousData,

// Initial data is applied when the query key is changed
initialData: {
pages: [initialData],
pageParams: [0],
},
});
};
export const usePostInfiniteQuery = (
postIds: number[],
initialData?: NewPublicPosts[],
) => {

return useInfiniteQuery({
queryKey: ["fetchPosts", postIds],
queryFn: ({ pageParam }) => fetchPosts(postIds, pageParam),

getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
if (!lastPage) {
return null;
}

if (lastPage.length < 10) return null;

return lastPageParam + 10;
},

initialPageParam: 0,

retry: 0,
enabled: false,

placeholderData: (previousData, previousQuery) => previousData,

// Initial data is applied when the query key is changed
initialData: {
pages: [initialData],
pageParams: [0],
},
});
};
8 Replies
robust-apricot
robust-apricot2y ago
yes, this is on purpose. When the key changes, a new cache entry is created, so initialData is applied for that entry
conscious-sapphire
conscious-sapphire2y ago
So should initialData and placeholderData be mutually exclusive?
robust-apricot
robust-apricot2y ago
if you only want initialData for a specific queryKey (your "first" one) - you need to be explicit
fair-rose
fair-roseOP2y ago
how can I do that?
robust-apricot
robust-apricot2y ago
by setting intialData to undefined if you don't want initial data ? usual pagination example is:
function MyComponent({ initialData }) {
const [page, setPage] = useState(0)
const { data } = useQuery({
queryKey: ['thing', page],
queryFn: () => getThing(page),
placeholderData: keepPreviousData,
initialData: page === 0 ? initialData : undefined
})
}
function MyComponent({ initialData }) {
const [page, setPage] = useState(0)
const { data } = useQuery({
queryKey: ['thing', page],
queryFn: () => getThing(page),
placeholderData: keepPreviousData,
initialData: page === 0 ? initialData : undefined
})
}
since you don't want initialData for page 2 or 3, we only set it for the first page.
fair-rose
fair-roseOP2y ago
in the above example every time there is a new query there will be the initial data In this example the initialData should only be there on the very first query all other ones are meant to use placeholderData until the new data is loaded
export const usePostInfiniteQuery = (
postIds: number[],
initialData?: NewPublicPosts[],
) => {

return useInfiniteQuery({
queryKey: ["fetchPosts", postIds],
queryFn: ({ pageParam }) => fetchPosts(postIds, pageParam),

getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
if (!lastPage) {
return null;
}

if (lastPage.length < 10) return null;

return lastPageParam + 10;
},

initialPageParam: 0,

retry: 0,
enabled: false,

placeholderData: (previousData, previousQuery) => previousData,

// Initial data is applied when the query key is changed
initialData: {
pages: [initialData],
pageParams: [0],
},
});
};
export const usePostInfiniteQuery = (
postIds: number[],
initialData?: NewPublicPosts[],
) => {

return useInfiniteQuery({
queryKey: ["fetchPosts", postIds],
queryFn: ({ pageParam }) => fetchPosts(postIds, pageParam),

getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
if (!lastPage) {
return null;
}

if (lastPage.length < 10) return null;

return lastPageParam + 10;
},

initialPageParam: 0,

retry: 0,
enabled: false,

placeholderData: (previousData, previousQuery) => previousData,

// Initial data is applied when the query key is changed
initialData: {
pages: [initialData],
pageParams: [0],
},
});
};
robust-apricot
robust-apricot2y ago
again, if you say:
initialData: {
pages: [initialData],
pageParams: [0],
},
initialData: {
pages: [initialData],
pageParams: [0],
},
then yes, it will be for every entry
fair-rose
fair-roseOP2y ago
ok, thank you so much for all your help.

Did you find this page helpful?