24.06.03 12:35 작성
·
485
0
안녕하세요. 강사님
예제를 보고 하던 중 suspense
가 동작하지 않아 질문드립니다.
처음 예시로 알려주신 react-query의 isPending
을 사용한 로딩처리는 잘 동작하지만 마지막에 알려주신 useSuspense(useSuspenseInfiniteQuery, useSuspenseQuery
)들을 사용하는 경우 동작하지 않네요..
*팔로우 중
을 선택해도 suspense에 설정한 로딩 컴포넌트가 나오지 않고 딜레이된 시간(5초) 후 데이터가 보여집니다.
로딩 컴포넌트도 회전하지 않고 멈춰있습니다.
어떤부분을 봐야할까요?ㅠㅠ
반대로 이런 증상을 경험하니 이전 데이터가 먼저 보여진 후 5초 뒤에 최신 데이터로 보여지므로 사용자가 잘 못된 데이터를 표시 할 수 있다는걸 배울 수 있었습니다.😎
소스코드
const HomePage = async () => {
return (
<HomeContextProvider>
<HomeTopTab />
<WriteForm />
<Suspense fallback={<Loader />}>
<TabDividerSuspense />
</Suspense>
</HomeContextProvider>
);
};
const TabDividerSuspense = async () => {
const queryClient = new QueryClient();
await queryClient.prefetchInfiniteQuery({
queryKey: ["tweet", "recommends"],
queryFn: getPostRecommends,
initialPageParam: 0,
});
const dehydratedState = dehydrate(queryClient);
return (
<HydrationBoundary state={dehydratedState}>
<TabDivider />
</HydrationBoundary>
);
};
const TabDivider = () => {
const { tab } = useContext(HomeContext);
return tab === "recommended" ? <TweetList /> : <FollowingList />;
};
const TweetList = () => {
const { ref, inView } = useInView();
const { data, fetchNextPage, hasNextPage, isFetching, isPending } =
useSuspenseInfiniteQuery<
Post[],
object,
InfiniteData<Post[]>,
[string, string],
number
>({
queryKey: ["tweet", "recommends"],
queryFn: getPostRecommends,
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.at(-1)?.postId,
});
useEffect(() => {
if (inView) {
!isFetching && hasNextPage && fetchNextPage();
}
}, [fetchNextPage, hasNextPage, inView, isFetching]);
const tweets = useMemo(() => {
if (data) {
return data.pages.flat();
}
}, [data]);
return (
<>
{tweets?.map((tweet) => (
<Tweet post={tweet} key={tweet.postId} />
))}
{isPending && <Loader />}
<div ref={ref} />
</>
);
};
추가 질문
빌드 후 네트워크 탭에서 home
을 확인해보면 post 글 들이 모두 html로 변환되어 내려 오고 있습니다!
(dev에서는 템플릿?으로 표현되더라고요)
저는 html이 아닌 데이터 형태로 내려와 useQuery로 해당 키로 접근해서 그냥 데이터를 가져올 줄 알았는데..그게 아닌가보네요.
혹시 좀 더 자세히 설명 좀 부탁드려도 될까요?ㅠ
그리고 home
의 미리보기
탭에서는 post글들이 아닌 로딩 컴포넌트가 보입니다. (위의 사진에 응답
탭에서는 post글 들이 존재하고요)
로딩 컴포넌트가 보이는 이유는 하이드레이션이 처리되기 전이라 그런게 맞나요?
지금 자료를 다시 찾으려니 못 찾고 있는데.. suspense를 사용할 경우 완성된 화면이 아닌 로딩화면을 먼저 내려주므로 seo에는 나쁠 수 있다라는 글을 본적이 있던 것 같은데..맞을까요?
*SEO 관련해서 추가로 궁금한건 강의가 따로 있다고 영상에서 말씀하셔서 거기까지 보고 필요할 경우 질문 한번 더 드리겠습니다.👍
답변 2
0
2024. 06. 04. 15:11
로딩 컴포넌트 회전은
부분 추가되어 있어야 하고요.
지금 뭔가 이상하네요. 지금 상태는 SSR이 되면 안 되고 로딩이 떠야하는 상태입니다. 지금 빌드된 코드랑 dev 코드랑 서로 다른 코드 같습니다.
0
2024. 06. 04. 14:48
Loading.tsx 없고 prefetch 있는 경우
컨텐츠 SSR 됨(다만 handlers.ts에서 delay를 걸어둔 경우 첫 로딩이 오래걸림)
SSR이 제일 잘 되나 prefetch가 끝나야 화면이 보이므로 사용자가 답답해할 수 있음
Loading.tsx 없고 useSuspenseQuery만 있는 경우
fallback 부분이 없어서 그런지 무한 요청 보내짐(사용X)
Loading.tsx 있고 prefetch 있는 경우는
Loading.tsx가 뜨고 3초 뒤에 게시글이 뜸. 따라서 SSR 안 됨
metadata나 generateMetadata로 SSR 정보 넣어줘야 함
Loading.tsx 있는데 Suspense도 하나 더 있고 prefetch는 있는 경우
Suspense fallback이 뜨고 3초 뒤에 게시글이 뜸. 따라서 SSR안 됨
컨텐츠 SSR 안 됨. metadata나 generateMetadata로 SSR 정보 넣어줘야 함
Loading.tsx 있는데 prefetch는 없는 경우
컨텐츠 SSR 안 됨. metadata나 generateMetadata로 SSR 정보 넣어줘야 함
isPending: true일 때 로딩 보여주게 직접 코딩해야 함
여기까지 알 수 있는 점: Loading.tsx도 Suspense의 일종이고, Suspense는 prefetchQuery가 있는 경우 작동한다.
Loading.tsx와 prefetchQuery 중간에 Suspense가 있으면 그게 작동한다. 그 이유는 Loading.tsx도 Suspense라서 Suspense구조가 Loading.tsx->중간 Suspense->prefetchQuery이면 prefetchQuery는 중간 Suspense에 걸림.
Loading.tsx 있고 Suspense + useQuery 있고 prefetch 없는 경우
Loading.tsx 작동 안하고 Suspense 작동 안 함. isPending: true의 로딩이 보여짐
Loading.tsx 있고 Suspense + useSuspenseQuery 있고 prefetch 없는 경우
Loading.tsx 작동 안하고 Suspense fallback의 로딩이 보여짐
서버에서 한번, 프론트에서 한 번 총 두 번 요청하므로 비효율
Loading.tsx 있고 Suspense 없이 useSuspenseQuery 쓰는 경우
Loading.tsx 씀.
서버에서 한번, 프론트에서 한 번 총 두 번 요청하므로 비효율
결론:
SSR이 전체적으로 완벽하게 되길 원하면, Loading.tsx & 별도 Suspense 없이 prefetchQuery만 사용
useSuspense 시리즈 문제 있으므로 쓰지 말 것
SSR을 metadata로 대신 할 수 있다면 Suspense를 두고 prefetchQuery하거나 Suspense 없이 useQuery 쓰면 됨.
Loading.tsx를 쓸지 별도의 Suspense를 둘지 선택하는 기준: Loading.tsx는 페이지 전체를 로딩하므로 부분만 로딩하고 싶다면 별도의 Suspense 사용
2024. 06. 04. 23:15
강사님 자세한 설명 감사합니다.
말씀하신
generateMetadata
와metadata
부분을 보면 SEO(검색 엔진 최적화)를 말씀해주신것 같은데.. SSR이 서버사이드 랜더링 말고 다른 단어?가 있나요?"컨텐츠 SSR 안 됨. metadata나 generateMetadata로 SEO(
SSR)정보 넣어줘야 함" 일까요?