24.06.02 13:55 작성
·
141
0
안녕하세요 선생님
홈에서 찜했다, 안했다 잘 작동하고
상세페이지로 이동하면 찜하기 데이터가 제대로 내려오지 않는 부분을 확인했습니다.
호출은 아래와 같이 하고있습니다.
/src/app/(afterLogin)/[username]/status/[id]/page.tsx
import BackButton from "@/app/(afterLogin)/_component/BackButton";
import style from './singlePost.module.scss';
import Post from "@/app/(afterLogin)/_component/Post";
import CommentForm from "@/app/(afterLogin)/[username]/status/[id]/_component/CommentForm";
import SinglePost from '@/app/(afterLogin)/[username]/status/[id]/_component/SinglePost';
import Comments from '@/app/(afterLogin)/[username]/status/[id]/_component/Comments';
import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query';
import { getSinglePost } from '@/app/(afterLogin)/[username]/status/[id]/_lib/getSinglePost';
import { getComments } from '@/app/(afterLogin)/[username]/status/[id]/_lib/getComments';
type Props = {
params: { id: string}
}
export default async function Pasge({ params }: Props) {
console.log('----------------------------- single post params', params);
const { id } = params;
const queryClient = new QueryClient();
await queryClient.prefetchQuery({ queryKey: ['posts', id], queryFn: getSinglePost });
await queryClient.prefetchQuery({ queryKey: ['posts', id, 'comments'], queryFn: getComments });
const dehydratedState = dehydrate(queryClient);
return (
<div className={style.main}>
<HydrationBoundary state={dehydratedState}>
<div className={style.header}>
<BackButton/>
<h3 className={style.headerTitle}>게시하기</h3>
</div>
<SinglePost id={id} />
<CommentForm id={id} />
<div>
<Comments id={id} />
</div>
</HydrationBoundary>
</div>
)
}
/src/app/(afterLogin)/[username]/status/[id]/_component/SinglePost.tsx
'use client';
import { Post as IPost } from '@/models/Post'
import { useQuery } from '@tanstack/react-query'
import { getSinglePost } from '@/app/(afterLogin)/[username]/status/[id]/_lib/getSinglePost';
import Post from '@/app/(afterLogin)/_component/Post';
export default function SinglePost({id, noImage}: {id: string, noImage?: boolean}) {
const { data: post, error } = useQuery<IPost, Object, IPost, [_1: string, _2: string]>({
queryKey: ['posts', id],
queryFn: getSinglePost,
staleTime: 60 * 1000,
gcTime: 300 * 100,
});
console.log(post, '--------------------------single post');
if (error) {
return (
<div style={{
height: 100, alignItems: 'center', fontSize: 31, fontWeight: 'bold', display: 'flex', justifyContent: 'center'
}}>게시글을 찾을 수 없습니다.</div>
)
}
if (!post) {
return null;
}
return <Post post={post} key={post.postId} noImage={noImage} />
}
찜하기 코드
export default function ActionButtons({ white, post }: Props) {
const queryClient = useQueryClient();
const { data: session } = useSession();
const commented = !!post.Comments?.find(d => d.userId === session?.user?.email);
const reposted = !!post.Reposts?.find(d => d.userId === session?.user?.email);
const liked = !!post.Hearts?.find(d => d.userId === session?.user?.email);
const { postId } = post;
const heart = useMutation({
mutationFn: () => {
return fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/posts/${postId}/heart`, {
method: 'post',
credentials: 'include',
})
},
onMutate() {
const queryCache = queryClient.getQueryCache();
const queryKeys = queryCache.getAll().map(cache => cache.queryKey);
console.log('queryKey', queryKeys);
queryKeys.forEach((queryKey) => {
if (queryKey[0] === 'posts') {
const value: Post | InfiniteData<Post[]> | undefined = queryClient.getQueryData(queryKey);
if (value && 'pages' in value) {
const obj = value.pages.flat().find(d => d.postId === postId);
if (obj) { // 존재는 하는지?
const pageIndex = value.pages.findIndex(page => page.includes(obj));
const index = value.pages[pageIndex].findIndex(d => d.postId === postId);
const shallow = produce(value, draft => {
draft.pages[pageIndex][index].Hearts = [{ userId: session?.user?.email as string }];
draft.pages[pageIndex][index]._count.Hearts += 1;
})
queryClient.setQueryData(queryKey, shallow);
}
} else if (value) {
// 싱글 포스트인 경우
if (value.postId === postId) {
const shallow = {
...value,
Hearts: [...value.Hearts, { userId: session?.user?.email as string }],
_count: {
...value._count,
Hearts: value._count.Hearts + 1,
}
}
queryClient.setQueryData(queryKey, shallow);
}
}
}
})
},
onError() {
},
onSettled() {
}
});
다른 찜하기 질문에서
키를가지고 호출하지 않해서라고 하신걸 봤었는데,
위와 같은 경우에는 클라이언트 서버에서 쿼리키를 가지고 호출했는데 데이터가 잘 안내려오는 것을 확인했습니다.
찜을 눌렀을때
찜을 누르고 해당글 상세로 이동했을때
이러한 경우에는 찜하기를 누르고 추가적인 작업이 필요한지 궁금합니다. 예를들면 찜하기를 누르고 해당 쿼리키의 데이터를 호출해야한다는지... 혹은 제가 잘못호출한것이라면 알려주시면 감사하겠습니다.
2024. 06. 02. 19:01
3이 맞습니다.
홈 화면에서 각각 다른 계정으로 3번 눌렀는데,
상세화면갔을때 저렇게 나왔습니다.
새로고침하면 제대로 나옵니다.