찜하기 관련 질문드립니다.
214
작성자 없음
작성한 질문수 0
안녕하세요 상세페이지에서 찜하기 요청을 하게되면 users/favorite/${peopleId}로 post 요청을 보내게되고 그럼 users/favorite api에 찜한 사람들의 목록이 추가됩니다.
찜하기를 눌렀을경우 아이콘의 컬러를 변경시켜야해서 getQueryData로 찜한 사람들의 목록 을 가져오려고 하였는데
const { data: likePeopleList } = useQuery<GetPeoples>({
queryKey: ["get", "likepeoples"],
queryFn: getLikePeoples,
staleTime: 60 * 1000, // fresh -> stale, 5분이라는 기준
gcTime: 300 * 1000,
});위에 코드가 없으면 likeQuery를 가져오지 못하고있는것같습니다. getQueryData로 가져오는 방법이 잘못된걸까요? 다른 좋은 방법있다면 여쭤보고싶습니다.
밑에는 전체 코드입니다.
type Props = {
peopleId: string;
};
export default function PeoplePosts({ peopleId }: Props) {
const { data } = useQuery<
GetPeoplePost,
Object,
GetPeoplePost,
[_1: string, _2: string, _3: string]
>({
queryKey: ["get", "peoplesDetail", peopleId],
queryFn: getPeopleDetail,
});
const { data: likePeopleList } = useQuery<GetPeoples>({
queryKey: ["get", "likepeoples"],
queryFn: getLikePeoples,
staleTime: 60 * 1000, // fresh -> stale, 5분이라는 기준
gcTime: 300 * 1000,
});
const {
content,
nickname,
userFileUrl,
favoriteCount,
viewCount,
softSkill,
techStack,
links,
position,
alarmStatus,
year,
} = data?.data ?? {};
const queryClient = useQueryClient();
const likeQuery = queryClient.getQueryData<GetPeoples>([
"get",
"likepeoples",
]);
console.log("likeQuery", likeQuery);
const liked = !!likeQuery?.data.find(
(item) => item.userId === Number(peopleId),
);
console.log("liked", liked);
const like = useMutation({
mutationFn: (peopleId: string) => {
return fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}/users/favorite/${peopleId}`,
{
method: "post",
},
);
},
onMutate(peopleId: string) {
const oldData = queryClient.getQueryData<GetPeoples>([
"get",
"likepeoples",
]);
if (oldData) {
const newData = {
...oldData,
data: oldData.data.map((item) => ({
...item,
userId: Number(peopleId),
})),
};
queryClient.setQueryData(["get", "likepeoples"], newData);
}
},
});
const unLike = useMutation({
mutationFn: (peopleId: string) => {
return fetch(
`${process.env.NEXT_PUBLIC_BASE_URL}/users/favorite/${peopleId}`,
{
method: "delete",
},
);
},
onMutate(peopleId: string) {
const oldData = queryClient.getQueryData<GetPeoples>([
"get",
"likepeoples",
]);
if (oldData) {
const deleteData = {
...oldData,
data: oldData.data.filter((item) => item.userId !== Number(peopleId)),
};
queryClient.setQueryData(["get", "likepeoples"], deleteData);
}
},
});
const onLike: MouseEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault();
if (liked) {
unLike.mutate(peopleId);
} else {
like.mutate(peopleId);
}
};
return (
<div className="flex flex-col">
<div className="flex flex-col gap-4 border-b pb-10">
<div className="flex items-center gap-[10px]">
<Image
src={`${userFileUrl}`}
alt="유저프로필"
width={30}
height={30}
/>
<h1 className="text-[32px] font-bold">{nickname}</h1>
<div>
<BlueTextBox textSize="12px" textToShow={`${position}`} />
</div>
</div>
<div className="flex flex-col gap-2">
{softSkill
?.split(",")
.map((skill, i) => <HashTag text={skill} key={i} />)}
</div>
<div className="flex gap-3">
<HeartEyeIconBox count={favoriteCount as number} icon={heartIcon} />
<HeartEyeIconBox count={viewCount as number} icon={eyeIcon} />
</div>
</div>
<div className="mt-[42px] flex flex-col gap-[50px]">
<div className="people-post-grid">
<h1 className="text-[22px] font-bold">경력</h1>
<h3>{year}</h3>
</div>
<div className="people-post-grid">
<h1 className="text-[22px] font-bold">사용언어</h1>
<div className="flex gap-2">
{techStack
?.split(",")
.map((stack, i) => (
<TechStack techStack={stack} showText key={`stack${i}`} />
))}
</div>
</div>
<div className="flex flex-col gap-3">
<h1 className="text-[22px] font-bold">자기소개</h1>
<p>{content}</p>
</div>
<div className="flex flex-col gap-3">
<h1 className="text-[22px] font-bold">Link</h1>
<Link href={links as string}>{links}</Link>
</div>
</div>
<div className="mt-[60px] flex gap-[13px] self-center">
<button
className={`h-[58px] w-[142px] rounded-md bg-neutral-orange-500 font-bold ${alarmStatus ? "text-neutral-white-0" : "text-neutral-black-800"}`}
>
{alarmStatus ? "제안하기" : "제안불가"}
</button>
<button
onClick={onLike}
className="flex h-[58px] w-[58px] flex-col items-center justify-center rounded-md border"
>
{liked ? (
<Image
src={fillHeartIcon}
alt="하트아이콘"
width={20}
height={20}
/>
) : (
<Image src={heartIcon} alt="하트아이콘" width={20} height={20} />
)}
<h5 className="text-[12px]">{favoriteCount}</h5>
</button>
</div>
</div>
);
}
답변 1
0
getQueryData는 한 번이라도 같은 키로 useQuery나 setQueryData로 해당 키가 생성되어야 사용할 수 있습니다. 아마도 useQuery/setQueryData를 이전에 하신 적이 없을 겁니다.
캡처링부분 질문있습니다.
0
76
2
깃에 소스코드를 찾을 수 없습니다.
0
114
2
useInfiniteQuery promise와 react use 사용시 페이지 무한 로딩
0
98
1
import 파일 경로를 찾지 못 해서 에러가 발생합니다.
0
111
2
css 라이브러리 추천 부탁드립니다
0
141
2
팔로우 추천 목록이 빈 배열로 들어옵니다.
0
133
1
게시물 업로드 시 userId가 undefined로 들어가는 오류
0
119
1
useSuspenseQuery 사용 시 SSR 401 이슈 관련
0
173
1
리액트 쿼리 useinfinitequery 무한스크롤 구현 시 페이지가 이동할 경우 데이터가 보존되게 할 수 있나요??
0
186
3
폴링이 필요없는 이유
0
93
2
next Request Memoization과 react cache
0
110
2
seo 최적화 기준은 데이터 fetching인가요 아님 데이터 렌더링인가요?
0
84
2
next.js 서버fetch 에러 fallback ui 구현 방법
0
173
2
프레임워크 여론 파악법
0
125
2
필터옵션이 많은 페이지에서 서버 fetch를 하는게 맞는걸까요??
0
103
2
서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.
0
102
2
template.tsx 내 서버fetch 응답값과 클라이언트 컴포넌트 상태값 싱크가 맞지 않는 이슈
0
66
2
Auth.js 사용 시 authorize 함수가 호출되지 않습니다
0
132
2
next.js 에서 로그인에 관하여
0
139
1
Next의 route handler에 대한 질문이 있습니다.
0
101
2
게시판 리스트 만들때 use client를 어디서부터 집어넣어야할지 모르겠습니다
0
99
2
프라이빗 폴더를 해야 하는 이유가 모호한 것 같아요.
0
85
2
vanilla-extract 못찾는 문제
0
230
2
fetch 캐싱과 revalidate 관련
0
86
2





