useEffect와 useQuery

주유구·2023년 11월 6일
0

memorious-error

목록 보기
2/2

메모 페이지에서, 무한스크롤을 구현할 때 react-query를 쓰는 이유로 꽤 오랜 시간을 날렸다.
useQuery첫번째 array의 두번째 인자부터는 dependency인데, 이부분을 잘 숙지하지 못해 useEffect와 혼용한 탓에 조금 헤맸다.

결론적으로, react-intersection-observer라이브러리에서 inView값을 useQuery의 deps안에 넣어주는 게 덜 복잡했고, 백엔드에서 hasNextPage혹은 totalCount값으로 모든 메모의 갯수를 넘겨주는 게 필요하기도 했다.

import React, { useState } from "react";
import { useInView } from "react-intersection-observer";
import { useQuery } from "react-query";
import { useRecoilState } from "recoil";
import { memoBoard, memoContent, memoWrapper } from "./style";
import { rcMemoPage } from "../../store/atoms/memoAtoms";
import { instance } from "../../config";
/** @jsxImportSource @emotion/react */

function MemoContainer() {
    const [memoList, setMemoList] = useState([]);
    const [pageNum, setPageNum] = useRecoilState(rcMemoPage);
    const [ref, inView] = useInView();
    const memo = useQuery(
        ["getMemo", pageNum, inView],
        async () => {
            const response = await instance.get(`/api/memo/${pageNum}`);
            if (response.data.length === 0) return;
            setMemoList([...memoList, ...response.data.memoList]);
            if (inView && response.data.totalCount - pageNum * 9 > 0) {
                setPageNum(pageNum + 1);
            }
            return response.data;
        },
        {
            retryOnMount: false,
            refetchOnWindowFocus: false,
        },
    );

    return (
        <div css={memoWrapper}>
            <div css={memoBoard}>
                <div className="memo-scroll-board">
                    {memoList.map((e, i) => {
                        return (
                            <div key={e.memoContent + Math.random()} css={memoContent(i)}>
                                <p className="author-label">{e.author}</p>
                                <div className="content-area">
                                    <pre>{e.memoContent}</pre>
                                </div>
                                <p className="date-label">{e.createdDate}</p>
                            </div>
                        );
                    })}
                    {memo.isSuccess && <div style={{ height: "1px" }} ref={ref} />}
                </div>
            </div>
        </div>
    );
}

export default MemoContainer;

수정한 코드 전문

profile
뜨개질 어딕트 개발자

0개의 댓글