1 year ago

#340295

test-img

Hendry Lim

Using SWR Bound Mutation Across Nextjs Pages with useSWRInfinite

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,
  };
};

reactjs

next.js

swr

0 Answers

Your Answer

Accepted video resources