通过 useSWRInfinite 在 Nextjs 页面上使用 SWR 绑定突变
需要有关使用 useSWRInfinite 进行突变的帮助
预期
在我的帖子页面上,我使用 useSWRInfinite 来加载带有分页的帖子。它为我提供了一个可以在该页面上使用的有界突变
然后用户可以选择该帖子并转到 postDetails 页面,在那里他们可以查看帖子的详细信息并将其删除
在 postDetails 页面上,我想允许用户删除帖子,这将打开一个模式要求他确认删除。一旦用户单击确认删除,帖子将通过 axios.delete 调用删除,然后帖子将发生变化,用户将被发送回帖子页面。新的分页数据将不再显示已删除的帖子
问题
删除功能就是问题所在。当我使用 usePagination 挂钩来获取删除数据后调用的有界 mutate 函数时,出现密钥冲突错误。我还尝试使用 api 的密钥进行 mutate,但它不会更新缓存。
问题
我是否可以在 nextjs 页面上使用有界突变?或者我还应该做些什么来使我的删除功能正常工作?谢谢
// todo
const onDelete = async (postId: string) => {
await axios.delete(`/api/demo/posts/${postId}`);
//mutate(`/api/demo/posts`); - doesn't mutate the data
mutatePosts(); // mutates the data but gets conflicting keys
replace("/demo/posts");
};
调用 usePagination 函数的 mutate 会导致密钥冲突错误
const { mutate: mutatePosts } = usePagination<IPost>(`/api/demo/posts`);
使用 useSWRConfig() 中的 mutate 并传入 api key '/api/demo/posts' 根本不会更新缓存。
const { mutate } = useSWRConfig();
我使用了 usePagination,它是一个自定义挂钩,用于在帖子页面中进行 api 调用。 中的 nextjs 页面上使用有界 mutate
const {
paginatedData: paginatedPosts,
error,
isLoadingMore,
isReachedEnd,
setPage,
page,
mutate: mutatePosts,
} = usePagination<IPost>(`/api/demo/posts`, searchText);
但是,我无法在 postDetail 页面usePagination 自定义挂钩
import useSWRInfinite from "swr/infinite";
export const usePagination = <T>(url: string, searchText: string = "") => {
const PAGE_SIZE = 2;
const getKey = (pageIndex: number, previousPageData: T[]) => {
pageIndex = pageIndex + 1;
if (previousPageData && !previousPageData.length) return null; // reached the end
return `${url}?page=${pageIndex}&limit=${PAGE_SIZE}&searchText=${searchText}`;
};
const {
data,
size: page,
setSize: setPage,
error,
isValidating,
mutate,
} = useSWRInfinite(getKey);
const paginatedData: T[] = [].concat.apply([], data!);
const isLoadingMore = data && typeof data[page - 1] === "undefined";
const isReachedEnd = data && data[data.length - 1]?.length < PAGE_SIZE;
return {
paginatedData,
isLoadingMore,
isReachedEnd,
page,
setPage,
isValidating,
error,
mutate,
};
};
Need help on using mutation with useSWRInfinite
EXPECTED
On my posts page, I used useSWRInfinite to do load posts with pagination. it provides me a bounded mutation which I can use on that page
The user is then able to select the post and go to a postDetails page where they can see details of the post and delete it
On the postDetails page, I want to allow the user to delete a post which will open a modal asking him to confirm delete. Once the user clicks on confirm delete, the post will be deleted via an axios.delete call and then the posts will be mutated and user will be sent back to the posts page. the new paginated data will no longer show the deleted post
PROBLEM
The delete function is where the problem lies. When i use my usePagination hook to get the bounded mutate function which I call after deleting the data, I get a key conflict error. I also tried doing mutate with the key to my api but it doesn't update the cache.
QUESTION
Is there anyway I can use the bounded mutation across nextjs pages? or is there something else I should do to make my delete function works? Thanks
// todo
const onDelete = async (postId: string) => {
await axios.delete(`/api/demo/posts/${postId}`);
//mutate(`/api/demo/posts`); - doesn't mutate the data
mutatePosts(); // mutates the data but gets conflicting keys
replace("/demo/posts");
};
The mutate from calling the usePagination function will lead to key conflict error
const { mutate: mutatePosts } = usePagination<IPost>(`/api/demo/posts`);
Using the mutate from useSWRConfig() and passing in the api key '/api/demo/posts' will not update the cache at all.
const { mutate } = useSWRConfig();
I used usePagination which is a custom hook to make the api call in posts page. However, I am unable to use the bounded mutate here across nextjs pages in the postDetail page
const {
paginatedData: paginatedPosts,
error,
isLoadingMore,
isReachedEnd,
setPage,
page,
mutate: mutatePosts,
} = usePagination<IPost>(`/api/demo/posts`, searchText);
usePagination custom hook
import useSWRInfinite from "swr/infinite";
export const usePagination = <T>(url: string, searchText: string = "") => {
const PAGE_SIZE = 2;
const getKey = (pageIndex: number, previousPageData: T[]) => {
pageIndex = pageIndex + 1;
if (previousPageData && !previousPageData.length) return null; // reached the end
return `${url}?page=${pageIndex}&limit=${PAGE_SIZE}&searchText=${searchText}`;
};
const {
data,
size: page,
setSize: setPage,
error,
isValidating,
mutate,
} = useSWRInfinite(getKey);
const paginatedData: T[] = [].concat.apply([], data!);
const isLoadingMore = data && typeof data[page - 1] === "undefined";
const isReachedEnd = data && data[data.length - 1]?.length < PAGE_SIZE;
return {
paginatedData,
isLoadingMore,
isReachedEnd,
page,
setPage,
isValidating,
error,
mutate,
};
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论