T
TanStack2y ago
conscious-sapphire

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
other-emerald
other-emerald2y ago
yes, this is on purpose. When the key changes, a new cache entry is created, so initialData is applied for that entry
probable-pink
probable-pink2y ago
So should initialData and placeholderData be mutually exclusive?
other-emerald
other-emerald2y ago
if you only want initialData for a specific queryKey (your "first" one) - you need to be explicit
conscious-sapphire
conscious-sapphireOP2y ago
how can I do that?
other-emerald
other-emerald2y 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.
conscious-sapphire
conscious-sapphireOP2y 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],
},
});
};
other-emerald
other-emerald2y ago
again, if you say:
initialData: {
pages: [initialData],
pageParams: [0],
},
initialData: {
pages: [initialData],
pageParams: [0],
},
then yes, it will be for every entry
conscious-sapphire
conscious-sapphireOP2y ago
ok, thank you so much for all your help.

Did you find this page helpful?