인프런 커뮤니티 질문&답변

Sssekkk님의 프로필 이미지
Sssekkk

작성한 질문수

따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)

useSWRInfinite 관련

작성

·

427

·

수정됨

0

const listFetcher = async () => {
        const res = await apiClient.get(`/notices`, {
            params: {
                siteKey: sitekey || selectsite,
                keyword: searchData || null,
                page: page,
                size: 5,
                orderOption: sortModel.field || "createAt",
                orderSeq: sortModel.sort || "desc",
            },
        });
        console.log("res.data.payload.notices", res.data.payload.notices);
        return res.data.payload.notices;
    };

    const getKey = (pageIndex, previousPageData) => {
        if (previousPageData && !previousPageData.length) return null;

        return {
            url: `/notices?${pageIndex}`,
        };
    };

    const {
        data,
        error,
        size: page,
        setSize: setPage,
        isValidating,
        mutate,
    } = useSWRInfinite(getKey, listFetcher);
    const isInitialLoading = !data && !error;
    const posts = data ? [].concat(...data) : [];

    const [observedPost, setObservedPost] = useState("");

    useEffect(() => {
        // 포스트가 없다면 return
        if (!posts || posts.length === 0) return;
        // posts 배열안에 마지막 post에 id를 가져옵니다.
        const id = posts[posts.length - 1].noticeNo;
        // posts 배열에 post가 추가돼서 마지막 post가 바뀌었다면
        // 바뀐 post 중 마지막post를 obsevedPost로
        if (id !== observedPost) {
            setObservedPost(id);
            observeElement(document.getElementById(id));
        }
    }, [posts]);

    const observeElement = (element) => {
        if (!element) return;
        // 브라우저 뷰포트(ViewPort)와 설정한 요소(Element)의 교차점을 관찰
        const observer = new IntersectionObserver(
            // entries는 IntersectionObserverEntry 인스턴스의 배열
            (entries) => {
                // isIntersecting: 관찰 대상의 교차 상태(Boolean)
                if (entries[0].isIntersecting === true) {
                    console.log("마지막 포스트에 왔습니다.");
                    setPage(page + 1);
                    observer.unobserve(element);
                }
            },
            { threshold: 0.5 }
        );
        // 대상 요소의 관찰을 시작
        observer.observe(element);
    };

useSWRInfinite 포스트 작성중인데, 위와 같이 처리했더니 맨끝 스크롤 이동시 api 호출이 더이상 되지 않고 있는데 이유를 알고 싶습니다!

 

답변 1

0

안녕하세요, 인프런 AI 인턴이에요.

useSWRInfinite를 이용한 포스트 작성 중에 맨끝 스크롤 이동시 api 호출이 이뤄지지 않는 문제로 보입니다.

첫 번째로는 getKey 함수 반환값이 제대로 설정되어 있는지 확인해보세요. 현재 코드에서는 pageIndex만을 기준으로 URL을 반환하고 있습니다. 기존에 호출된 데이터가 없는 경우에는 null을 반환해야 하며, 기존에 호출된 데이터가 존재한다면 첫 번째 호출에서 가져온 데이터의 다음 데이터를 가져와야 합니다. 현재 샘플 코드에서는 이를 구현하지 않고 있으니 해당 부분을 구현해보세요.

두 번째로는 setPage 함수가 호출될 때 page 값이 제대로 증가되고 있는지 확인해보세요. 현재 코드에서는 setSize 함수가 setPage 함수와 같은 역할을 수행하기 때문에, setPage 함수를 호출할 경우 size 값이 적절히 증가되고 있는지 확인해보세요.

세 번째로는 IntersectionObserver의 threshold 값을 확인해보세요. 현재 설정된 값은 0.5로써, 화면에 보여지는 영역에서 대상 요소의 50% 이상이 보여지면 콜백 함수가 실행되도록 설정되어 있습니다. 해당 값은 상황에 따라 변경이 필요하니, 기존에 설정된 값이 적절한지 살펴보세요.

이상의 점들을 확인하고, 문제가 되는 부분을 수정해보시기 바랍니다. 참고로 코드 내부에서 setPage 함수를 호출할 때 기존 page 값에 1을 더해주고 있기 때문에, setPage(page + 1) 형태로 호출하지 않아도 됩니다.

수고하셨습니다!

Sssekkk님의 프로필 이미지
Sssekkk

작성한 질문수

질문하기