通过 useSWRInfinite 在 Nextjs 页面上使用 SWR 绑定突变

发布于 2025-01-17 04:04:47 字数 2473 浏览 1 评论 0原文

需要有关使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文