해결된 질문
작성
·
148
·
수정됨
0
안녕하세요 제로초님,
특정인 정보 api(api/users/{id}) response 관련 질문이 있습니다.
response에 Followers 배열이 있어
해당 유저를 팔로우 한 다른 사용자들을 얻고자 했습니다.
처음 시도는 강의에서 진행했던대로
prefetchQuery + useQuery 조합으로 데이터를 끌어오고자 했습니다.
하지만 이 경우에 Followers 배열이 빠진 상태로 응답이 돌아오고 있습니다.
한 100번 새로고침하면 1~2번만 붙어서 옵니다.
아래는 prefetchQuery + useQuery 조합 코드입니다.
// page.tsx
import Link from "next/link";
import { QueryClient, HydrationBoundary, dehydrate } from "@tanstack/react-query";
import getUserInfo from "./_lib/getUserInfo";
import getUserPosts from "./_lib/getUserPosts";
import Nav from "./_component/Nav";
import ProfileUserData from "./_component/ProfileUserData";
import UserPosts from "./_component/UserPosts";
import { Container, Userzone, Profile, HeaderPhotoZone } from "./page-style";
type Props = {
params: { username: string };
};
export default async function Username({ params }: Props) {
const { username } = params;
console.log("username : ", username);
const queryClient = new QueryClient();
await queryClient.prefetchQuery({
queryKey: ["user", username],
queryFn: getUserInfo,
});
await queryClient.prefetchQuery({
queryKey: ["posts", "user", username],
queryFn: getUserPosts,
});
return (
<Container>
<HydrationBoundary state={dehydrate(queryClient)}>
<Nav username={username} />
<Userzone>
<Profile>
<HeaderPhotoZone>
<Link href="/home">{/* <Image src={이미지} alt="header_photo"></Image> */}</Link>
</HeaderPhotoZone>
<ProfileUserData username={username} />
</Profile>
<UserPosts username={username} />
</Userzone>
</HydrationBoundary>
</Container>
);
}
//Nav.tsx
"use client";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import getUserInfo from "../_lib/getUserInfo";
import BackBtn from "../../_component/BackBtn";
import { Navigation } from "./style";
import { User } from "@/model/User";
type Prop = {
username: string;
};
export default function Nav({ username }: Prop) {
const { data } = useQuery<User, Object, User, [_1: string, _2: string]>({ queryKey: ["user", username], queryFn: getUserInfo });
console.log("네비게이션 유저 데이터 : ", data);
return (
<Navigation>
<BackBtn></BackBtn>
{data === undefined ? (
<div>프로필</div>
) : (
<div>
<div>{data?.nickname}</div>
<div>0 게시물</div>
</div>
)}
</Navigation>
);
}
//ProfileUserData.tsx
"use client";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import Link from "next/link";
import { useSession } from "next-auth/react";
import Tab from "./Tab";
import FollowButton from "../../_component/FollowButton";
import { ProfileUserdataMid, UserName, SignupDate, AboutFollower, ProfileUserdata, NoAccountId, NoAccountMsg, ProfileUserdataTop, AbsoluteProfileContainer } from "./style";
import { User } from "@/model/User";
import getUserInfo from "../_lib/getUserInfo";
type Prop = {
username: string;
};
export default function ProfileUserData({ username }: Prop) {
const { data: session } = useSession();
const { data } = useQuery<User, Object, User, [_1: string, _2: string]>({ queryKey: ["user", username], queryFn: getUserInfo });
console.log("프로필 유저 데이터 : ", data);
// const createdDate = new Date(data?.createdAt!);
if (data === undefined) {
return (
<>
<NoAccountId>@{username}</NoAccountId>
<NoAccountMsg>계정이 존재하지 않음</NoAccountMsg>
</>
);
}
// return null;
// 팔로우, 팔로잉 데이터 추가 필요
return (
<ProfileUserdata>
<ProfileUserdataTop>
<AbsoluteProfileContainer>
<div>아 몰랑</div>
</AbsoluteProfileContainer>
{/* 팔로우 버튼 확인 */}
{/* <Link href="/settings/profile">프로필 수정</Link> */}
{/* {session?.user?.email === data?.id ? <Link href="/settings/profile">프로필 수정</Link> : <FollowButton user={data} />} */}
</ProfileUserdataTop>
<ProfileUserdataMid>
<UserName>
<div>{data?.nickname}</div>
<div>@{data?.id}</div>
</UserName>
<SignupDate>
<svg viewBox="0 0 24 24" aria-hidden="true" height="1.25rem">
<g>
<path d="M7 4V3h2v1h6V3h2v1h1.5C19.89 4 21 5.12 21 6.5v12c0 1.38-1.11 2.5-2.5 2.5h-13C4.12 21 3 19.88 3 18.5v-12C3 5.12 4.12 4 5.5 4H7zm0 2H5.5c-.27 0-.5.22-.5.5v12c0 .28.23.5.5.5h13c.28 0 .5-.22.5-.5v-12c0-.28-.22-.5-.5-.5H17v1h-2V6H9v1H7V6zm0 6h2v-2H7v2zm0 4h2v-2H7v2zm4-4h2v-2h-2v2zm0 4h2v-2h-2v2zm4-4h2v-2h-2v2z"></path>
</g>
</svg>
{/* <div>{`가입일 ${createdDate.getFullYear()}년 ${createdDate.getMonth() + 1}월`}</div> */}
</SignupDate>
<AboutFollower>
<Link href="/follow">
<span>{data._count.Followings}</span> 팔로우 중
</Link>
<Link href="/followers">
<span>{data._count.Followers}</span> 팔로워
</Link>
</AboutFollower>
<Tab></Tab>
</ProfileUserdataMid>
</ProfileUserdata>
);
}
react-query 결과
때문에 다른 방법으로 prefetchQuery를 사용하지 않고
useQuery만을 사용해서 특정인 정보를 가져오는 시도를 했는데
이 경우에는 모두 Followers 배열이 같이 날아오더군요.
왜 이런 현상이 일어나는지 궁금해 질문 남깁니다.
아래는 useQuery만 사용한 코드는 page.tsx에 prefetchQuery만 빠진 것 이외에 다른 부분은 동일합니다.
//page.tsx
import Link from "next/link";
import { QueryClient, HydrationBoundary, dehydrate } from "@tanstack/react-query";
import getUserInfo from "./_lib/getUserInfo";
import getUserPosts from "./_lib/getUserPosts";
import Nav from "./_component/Nav";
import ProfileUserData from "./_component/ProfileUserData";
import UserPosts from "./_component/UserPosts";
import { Container, Userzone, Profile, HeaderPhotoZone } from "./page-style";
type Props = {
params: { username: string };
};
export default async function Username({ params }: Props) {
const { username } = params;
console.log("username : ", username);
const queryClient = new QueryClient();
// await queryClient.prefetchQuery({
// queryKey: ["user", username],
// queryFn: getUserInfo,
// });
await queryClient.prefetchQuery({
queryKey: ["posts", "user", username],
queryFn: getUserPosts,
});
// 개인 사용자 데이터 가져오는 것으로 수정해ㅑ함
// 이거 서버 컴포넌트인데 Nav 같은거는 client란 말이야 그래서 깜박거리는데 어카지;
return (
<Container>
<HydrationBoundary state={dehydrate(queryClient)}>
<Nav username={username} />
<Userzone>
<Profile>
<HeaderPhotoZone>
<Link href="/home">{/* <Image src={이미지} alt="header_photo"></Image> */}</Link>
</HeaderPhotoZone>
<ProfileUserData username={username} />
</Profile>
<UserPosts username={username} />
</Userzone>
</HydrationBoundary>
</Container>
);
}
react - query 결과
useQuery만 사용했을 때의 네트워크 탭
getUserInfo.tsx는 다음과 같습니다.
import { QueryFunction } from "@tanstack/query-core";
import { User } from "@/model/User";
const getUserInfo: QueryFunction<User, [_1: string, _2: string]> = async ({ queryKey }) => {
const [_1, username] = queryKey;
const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/users/${username}`, {
credentials: "include",
});
if (response.ok) return response.json();
};
export default getUserInfo;
답변 1
0
ssr을 할 때 로그인 여부를 판단해주는 쿠키가 들어있지 않아서 그렇습니다. 따로 서버 전용 queryFn 함수를 하나 만들어 헤더로 쿠키 넣어주셔야 합니다. 강의에 나오는 부분이라 해당 부분 들어보시면 됩니다.
바로 다음 강의에 나오는군요.
감사합니다.