Skip to content

Commit

Permalink
[Add] feed scroll intersect observer 사용으로 변경 #32
Browse files Browse the repository at this point in the history
why
비동기로 scrollEvent 를 감지하기 위해서 사용

how
intersection observer를 hook으로 분리하여 사용
  • Loading branch information
WooYeonSeo committed Nov 25, 2019
1 parent d6b1a03 commit 9e5f57e
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 13 deletions.
48 changes: 35 additions & 13 deletions client/src/composition/Feed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
import useScrollEnd from '../../hooks/useScrollEnd';
import WritingFeedContainer from './WritingFeed';
import useIntersect from '../../hooks/useIntersectObserver';
import styled from 'styled-components';

interface IFeed {
content: string;
Expand All @@ -23,26 +25,30 @@ const GET_FEEDS = gql`
}
`;

const Testdiv = styled.div`
height: 50px;
`;

interface FeedVars {
first: number;
currentCursor: string;
}
const OFFSET = 3;
const OFFSET = 4;
const FeedContainer = () => {
const [feeds, setFeeds] = useState<IFeed[]>([]);
const [cursor, setCursor] = useState<string>('9999-12-31T09:29:26.050Z');
const [isLoading, setIsLoading] = useState<boolean>(false);
const [isEnd, setIsEnd] = useState<boolean>(false);

const [ref, setRef] = useIntersect(checkIsEnd, {});

const checkEnd = useScrollEnd();
// hooks 에서 useQuery 1 부터 시작
const { loading, data, fetchMore } = useQuery<Feeds, FeedVars>(GET_FEEDS, {
variables: { first: OFFSET, currentCursor: cursor }
});

useEffect(() => {
checkEndFeed();
}, [checkEnd]);

const fetchMoreFeed = async () => {
async function fetchMoreFeed() {
setIsLoading(true);
const { data: value } = await fetchMore({
variables: {
first: OFFSET,
Expand All @@ -52,30 +58,46 @@ const FeedContainer = () => {
if (!fetchMoreResult) {
return prev;
}
if (!fetchMoreResult.feeds.length) {
setIsEnd(true);
return prev;
}

const { feeds: feedItems } = fetchMoreResult;
const lastFeedItem = feedItems[feedItems.length - 1];
// console.log('lastFeedItem ', fetchMoreResult);
setCursor(lastFeedItem.createdAt);

return Object.assign({}, prev, {
feed: [...prev.feeds, ...fetchMoreResult.feeds]
feeds: [...feedItems]
});
}
});

setFeeds([...feeds, ...value.feeds]);
};

const checkEndFeed = (): void => {
fetchMoreFeed();
};
// console.log('return FEEDS : ', feeds);
// console.log('final STATE : ', feeds);
// console.log('final STATE : ', cursor);
setIsLoading(false);
}

function checkIsEnd() {
if (!isEnd) {
fetchMoreFeed();
}
}

return (
<>
<WritingFeedContainer />
{feeds.map(feed => (
<Feed content={feed.content} createdAt={feed.createdAt} />
))}
<span onClick={fetchMoreFeed}>click</span>
<Testdiv onClick={fetchMoreFeed} ref={setRef as any}>
{isLoading ? 'LOADING' : ''}
{isEnd ? '마지막 글입니다' : ''}
</Testdiv>
</>
);
};
Expand Down
37 changes: 37 additions & 0 deletions client/src/hooks/useIntersectObserver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useState, useEffect, useCallback } from 'react';

const baseOption = {
root: null,
threshold: 0,
rootMargin: '0px'
};

const useIntersect = (interSectAction: any, option: any) => {
const [ref, setRef] = useState(null);

const checkIntersect = (
entry: IntersectionObserverEntry[],
observer: IntersectionObserver
) => {
if (entry[0].isIntersecting) {
// console.log('im in');
// observer.unobserve(entry[0].target);
interSectAction();
// observer.observe(entry[0].target);
}
};

useEffect(() => {
// console.log('aaaaaaaaa', ref);
let observer: any;
if (ref) {
observer = new IntersectionObserver(checkIntersect, baseOption);
// console.log('----------------', ref);
observer.observe(ref);
}
return () => observer && observer.disconnect();
}, [ref, option.root, option.threshold, option.rootMargin, checkIntersect]);
return [ref, setRef];
};

export default useIntersect;

0 comments on commit 9e5f57e

Please sign in to comment.