인프런 커뮤니티 질문&답변

작성자 없음

작성자 정보가 삭제된 글입니다.

Next + React Query로 SNS 서비스 만들기

useMutation 사용하기

게시물 팔로우 중 탭에서 게시물 업로드 오류 발생

24.06.07 16:53 작성

·

156

·

수정됨

0

게시물 추천 탭에서는 게시하기 버튼 클릭하면 게시물 업로드가 잘 작동됩니다. 그러나 팔로우 중 탭에서 게시하기 버튼을 클릭하면 에러가 발생합니다.

게시물 게시하기 코드는 아래와 같습니다.

 const mutation = useMutation({
    mutationFn: async (e: React.FormEvent) =>{
      e.preventDefault();
      const formData = new FormData();
      formData.append("content", content);
      imgPreview.forEach((img) => {
        img && formData.append("images", img.file);
      });

      return fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/posts`, {
        method: "post",
        credentials: "include",
        body: formData,
      });
    },
    onSuccess: async (response) => {
      const newPost = await response.json();
      setContent("");
      setImgPreview([]);
      if (queryClient.getQueryData(["posts", "recommends"])) {
        queryClient.setQueryData(
          ["posts", "recommends"],
          (prev: { pages: Post[][] }) => {
            const shallow = { ...prev, pages: [...prev.pages] };
            shallow.pages[0] = [...shallow.pages[0]];
            shallow.pages[0].unshift(newPost);
            return shallow;
          }
        );
      }

      if(queryClient.getQueryData(["posts", "followings"])) {
        console.log("get", queryClient.getQueryData(["posts", "followings"]));
        queryClient.setQueryData(
          ["posts", "followings"],
          (prev: { pages: Post[][] }) => {
            const shallow = { ...prev, pages: [...prev.pages] };
            shallow.pages[0] = [...shallow.pages[0]];
            shallow.pages[0].unshift(newPost);
            return shallow;
          }
        );
      }
    },
    onError: (error) => {
      console.error(error);
      alert("업로드 중 에러가 발생했습니다");
    },
  });

최근 새소식을 보고 useSuspenseQuery 가 문제가 있다는 것을 보고 Suspense 없애고 기존에 사용한 TabDecider 컴포넌트로 변경했습니다.

// src\app\(afterLogin)\home\page.tsx

export default async function Home() {
  const session = await auth();
  return (
    <main className={styles.main}>
      <TabContextProvider>
        <Tab />
        <PostForm me={session} />
        <TabDecider />
      </TabContextProvider>
    </main>
  );
}

 

네트워크 탭에서 posts 요청은 성공했다고 나와있습니다.

새로고침하면 업로드가 제대로 되지만 게시하기 버튼 클릭하면 onError에서 발생하는 '업로드 중 에러 발생' 알림창이

나옵니다.

react-query devtools에서 mutation 에러를 확인하니

인피니트 스크롤링하는 pages에 관한 오류가 나왔습니다.

FollowingPosts 컴포넌트와 PostForm에서 queryClient.getQueryData(["posts","followings"] 에서 받는 데이터를 출력해보니 아래와 같은 데이터 구조를 가지고 있습니다.

FollowingPosts 컴포넌트 코드는 다음과 같습니다.

export default function FollowingPosts() {
  const { isPending, data } = useQuery<PostType[]>({
    queryKey: ["posts", "followings"],
    queryFn: getFollowingPosts,
    staleTime: 60 * 1000,
    gcTime: 300 * 1000,
  });

  if (isPending) return <Loading />;
  console.log("data2", data);

  return data?.map((post) => <Post key={post.postId} post={post} />);
}

FollowingPosts 컴포넌트에서는 useInifiniteQuery가 아닌 useQuery를 통해 데이터를 받아와서 데이터 안에 있는 pages가 없어서 이런 오류가 나오는걸까요??

우선 useInfiniteQuery로 변경해 게시물을 등록하면

잘 작동되는 것은 확인했습니다.

답변 2

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2024. 06. 07. 19:29

네네 무한스크롤 적용할 페이지는 모두 useInfiniteQuery로 하셔야합니다!

0

인프런 AI 인턴님의 프로필 이미지

2024. 06. 07. 16:56

안녕하세요, 인프런 AI 인턴입니다.

키키님의 질문에 대해 고민하신 부분에 좋은 접근을 하고 계신 것 같습니다. 질문 내용을 바탕으로 확인할 수 있는 몇 가지 요소에 대해 설명드리겠습니다.

  1. onError에서 발생하는 ‘업로드 중 에러 발생’ 알림창 문제: 이 문제는 useMutation에서 onSuccess 부분에서 prev.pages를 사용하려고 할 때 prev.pages 값이 없다거나 iterable하지 않음을 의미합니다. 이는 주로 무한 스크롤 구조(useInfiniteQuery 사용 시)에서 발생하는 문제로, 이러한 경우 데이터 구조는 { pages: [][] }와 같이 되어 있어야 하며, 각 페이지는 배열 형태의 데이터 컬렉션을 가져야 합니다. 따라서, prev.pages에 접근하려 할 때 적절한 데이터 구조를 가지고 있지 않으면 에러가 발생할 수 있습니다.

  2. FollowingPosts 컴포넌트와 데이터 구조 문제: FollowingPosts 컴포넌트에서 useQuery 대신 useInfiniteQuery를 사용하면 문제가 해결된 것으로 보아, 실제로 ["posts", "followings"] 쿼리 키로 조회되는 데이터 구조가 useInfiniteQuery에 적합한 형태로 되어 있는 것 같습니다. useQuery는 단일 페이지 데이터를 위한 것이라서, 무한 스크롤이나 페이지네이션을 구현할 때는 useInfiniteQuery를 사용하는 게 적합합니다.

이러한 분석을 바탕으로, 다음과 같은 해결 방향을 제안드립니다:

  • 게시물 업로드 후 캐시 업데이트를 할 때, useInfiniteQuery로 가져온 데이터 구조에 맞게 onSuccess에서 캐시 업데이트 로직을 조정하세요. 즉, queryClient.setQueryData()를 사용할 때, prev.pages 데이터 구조에 맞춰 적절히 데이터를 삽입하거나 갱신하도록 합니다.
  • FollowingPosts 컴포넌트에서는 이미 useInfiniteQuery로 변경하여 잘 작동하는 것을 확인하셨다니, useInfiniteQuery를 사용하는 방식을 유지하는 것이 좋아 보입니다.

이와 유사한 상황을 다루는 예시로, 무한 스크롤 구현 시 발생할 수 있는 문제와 해당 문제를 해결하는 방법에 대해 설명한 문서나 포럼 글을 참고하시는 것도 좋습니다. 공식 문서에서 제공하는 React Query의 useInfiniteQuery 가이드를 살펴보시는 것도 추천드립니다.

질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.

현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏

추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기