|
1 | 1 | // hashtag/[tag].js |
| 2 | +import { GetStaticPropsContext } from 'next'; |
2 | 3 | import React, { useEffect } from 'react'; |
3 | | -import { useDispatch, useSelector } from 'react-redux'; |
| 4 | +import { useInView } from 'react-intersection-observer'; |
| 5 | +import { dehydrate, QueryClient, useInfiniteQuery } from 'react-query'; |
4 | 6 | import { useRouter } from 'next/router'; |
5 | | -import { END } from 'redux-saga'; |
6 | 7 |
|
7 | | -import axios from 'axios'; |
8 | | -import { LOAD_HASHTAG_POSTS_REQUEST } from '../../reducers/post'; |
| 8 | +import { loadHashtagPostsAPI } from '../../apis/post'; |
| 9 | +import Post from '../../interfaces/post'; |
9 | 10 | import PostCard from '../../components/PostCard'; |
10 | | -import wrapper from '../../store/configureStore'; |
11 | | -import { LOAD_MY_INFO_REQUEST } from '../../reducers/user'; |
12 | 11 | import AppLayout from '../../components/AppLayout'; |
13 | 12 |
|
14 | 13 | const Hashtag = () => { |
15 | | - const dispatch = useDispatch(); |
| 14 | + const [ref, inView] = useInView(); |
16 | 15 | const router = useRouter(); |
17 | 16 | const { tag } = router.query; |
18 | | - const { mainPosts, hasMorePosts, loadPostsLoading } = useSelector((state) => state.post); |
| 17 | + |
| 18 | + const { |
| 19 | + data, |
| 20 | + isLoading: loadPostsLoading, |
| 21 | + fetchNextPage, |
| 22 | + } = useInfiniteQuery<Post[]>( |
| 23 | + ['hashtag', tag], |
| 24 | + ({ pageParam = '' }) => loadHashtagPostsAPI(tag as string, pageParam), |
| 25 | + { |
| 26 | + getNextPageParam: (lastPage) => { |
| 27 | + return lastPage?.[lastPage.length - 1]?.id; |
| 28 | + }, |
| 29 | + }, |
| 30 | + ); |
| 31 | + |
| 32 | + const mainPosts = data?.pages.flat(); |
| 33 | + const isEmpty = data?.pages[0]?.length === 0; |
| 34 | + const isReachingEnd = isEmpty || (data && data.pages[data.pages.length - 1]?.length < 10); |
| 35 | + const hasMorePosts = !isEmpty && !isReachingEnd; |
| 36 | + const readToLoad = hasMorePosts && !loadPostsLoading; |
19 | 37 |
|
20 | 38 | useEffect(() => { |
21 | | - const onScroll = () => { |
22 | | - if (window.pageYOffset + document.documentElement.clientHeight > document.documentElement.scrollHeight - 300) { |
23 | | - if (hasMorePosts && !loadPostsLoading) { |
24 | | - dispatch({ |
25 | | - type: LOAD_HASHTAG_POSTS_REQUEST, |
26 | | - lastId: mainPosts[mainPosts.length - 1] && mainPosts[mainPosts.length - 1].id, |
27 | | - data: tag, |
28 | | - }); |
29 | | - } |
30 | | - } |
31 | | - }; |
32 | | - window.addEventListener('scroll', onScroll); |
33 | | - return () => { |
34 | | - window.removeEventListener('scroll', onScroll); |
35 | | - }; |
36 | | - }, [mainPosts.length, hasMorePosts, tag, loadPostsLoading]); |
| 39 | + console.log('inView!!!', inView); |
| 40 | + if (inView && readToLoad) { |
| 41 | + fetchNextPage(); |
| 42 | + } |
| 43 | + }, [inView, readToLoad, fetchNextPage]); |
37 | 44 |
|
38 | 45 | return ( |
39 | 46 | <AppLayout> |
40 | | - {mainPosts.map((c) => ( |
| 47 | + {mainPosts?.map((c) => ( |
41 | 48 | <PostCard key={c.id} post={c} /> |
42 | 49 | ))} |
| 50 | + <div ref={readToLoad ? ref : undefined} style={{ height: 50, backgroundColor: 'yellow' }} /> |
43 | 51 | </AppLayout> |
44 | 52 | ); |
45 | 53 | }; |
46 | 54 |
|
47 | | -export const getServerSideProps = wrapper.getServerSideProps(async (context) => { |
48 | | - const cookie = context.req ? context.req.headers.cookie : ''; |
49 | | - console.log(context); |
50 | | - axios.defaults.headers.Cookie = ''; |
51 | | - if (context.req && cookie) { |
52 | | - axios.defaults.headers.Cookie = cookie; |
| 55 | +export const getStaticProps = async (context: GetStaticPropsContext) => { |
| 56 | + const queryClient = new QueryClient(); |
| 57 | + const tag = context.params?.tag as string; |
| 58 | + if (!tag) { |
| 59 | + return { |
| 60 | + redirect: { |
| 61 | + destination: '/', |
| 62 | + permanent: true, |
| 63 | + }, |
| 64 | + }; |
53 | 65 | } |
54 | | - context.store.dispatch({ |
55 | | - type: LOAD_MY_INFO_REQUEST, |
56 | | - }); |
57 | | - context.store.dispatch({ |
58 | | - type: LOAD_HASHTAG_POSTS_REQUEST, |
59 | | - data: context.params.tag, |
60 | | - }); |
61 | | - context.store.dispatch(END); |
62 | | - await context.store.sagaTask.toPromise(); |
63 | | -}); |
| 66 | + await queryClient.prefetchInfiniteQuery(['hashtag', tag], () => loadHashtagPostsAPI(tag)); |
| 67 | + |
| 68 | + return { |
| 69 | + props: { |
| 70 | + dehydratedState: JSON.parse(JSON.stringify(dehydrate(queryClient))), |
| 71 | + }, |
| 72 | + }; |
| 73 | +}; |
64 | 74 |
|
65 | 75 | export default Hashtag; |
0 commit comments