솧디의 개발로그

React-qurey 무한스크롤 리랜더링발생 해결방안 (토큰문제) 본문

React 리액트/React 리액트

React-qurey 무한스크롤 리랜더링발생 해결방안 (토큰문제)

솧디_code 2022. 12. 18. 00:19

 

아래의 코드로 무한 스크롤 구현하니 로그인시 마이페이지 첫 겟요청시 리랜더링 이슈 발생,

새로고침해야 데이터가 캐싱되었습니다.

const fetchPostList = async (pageParam) => {
  const res = await axios.get(
    `http://localhost:5001/posts?&page=${pageParam}&limit=6`,{
				header:{
						authorization,
 },
},
  );
  const { posts, isLast } = res.data;
  return { posts, nextPage: pageParam + 1, isLast };
};

function Posts() {
  const { ref, inView } = useInView();
  const { data, status, fetchNextPage, isFetchingNextPage } = useInfiniteQuery(
    "posts",
    ({ pageParam = 1 }) => fetchPostList(pageParam),
    {
      getNextPageParam: (lastPage) =>
        !lastPage.isLast ? lastPage.nextPage : undefined,
    }
  );

  useEffect(() => {
    if (inView) fetchNextPage();
  }, [inView]);

  if (status === "loading") return <Loading />;
  if (status === "error") return <ErrorPage />;

 

위의 코드는 get요청 밖에서 하고 본 코드 안에서 pagepram을 겟요청으로 가져가는 형태로 로직을 구현하였습니다.

원인분석결과 최초 겟요청시 authorization이 null로 나와 get요청이 되지않은 것으로 확인했습니다.

그전에 refetch나 캐싱무효화 등 로직을 변경했는데도 안되는 상황이였습니다.

 

 

const MyComment = () => {
	//로컬스토리지 닉네임가져오기
	const nickname = localStorage.getItem("Nickname");
	const navigate = useNavigate();
	const { ref, inView } = useInView();

	const authorization = localStorage.getItem("Authorization");

	const { data, status, fetchNextPage, isFetchingNextPage, error, refetch } =
		useInfiniteQuery(
			["myComment"],
			async ({ pageParam = 1 }) => {
				const { data } = await axios.get(
					`${BASE_URL}/member/auth/mypage/comments?page=${pageParam}&size=3`,
					{
						headers: {
							authorization,
						},
					},
				);
				const { myPageList: page, isLast } = data;
				return { page, nextPage: pageParam + 1, isLast };
			},
			{ retry: 1 },
			{
				getNextPageParam: lastPage =>
					!lastPage.isLast ? lastPage.nextPage : undefined,
			},
			{
				onError: error => {
					console.log(error.response);
				},
			},
		);

	useEffect(() => {
		if (inView) fetchNextPage();
	}, [inView]);

	if (status === "loading")
		return (
			<Box variant="spinner-wrap">
				<Flex jc="center" ai="center">
					<Image src={spinner} alt="로딩중" variant="spinner" />
				</Flex>
			</Box>
		);
	if (error?.response.data === "작성한 댓글이 없습니다.") {
		return (
			<Box variant="spinner-wrap">
				<Flex fd="column" jc="center" ai="center" gap="100px">
					<Strong variant="warning">작성한 댓글이 없습니다😭</Strong>
					<Button onClick={() => navigate(-1)} variant="cafe-review-post">
						돌아가기
					</Button>
				</Flex>
			</Box>
		);
	}
	if (status === "error")
		return (
			<Box variant="spinner-wrap">
				<Flex fd="column" jc="center" ai="center" gap="100px">
					<Strong variant="warning">
						에러입니다.😭 빠른 시일 내에 해결하겠습니다.
					</Strong>
					<Button onClick={() => navigate(-1)} variant="cafe-review-post">
						돌아가기
					</Button>
				</Flex>
			</Box>
		);

이번엔 데이터 안에 또 데이터 요청을 넣는형태로 변경하였고, get요청시에도 authorization담기도록 로직을 변경하였습니다.

retry 횟수도 기본 3회에서 1회로 수정하여 로딩시간을 단축하였습니다.

위 코드로 진행하니 리랜더링 이슈가 해결되었습니다.

Comments