다이나믹 라우팅 렌더링, useEffect dependency의 이해

성찬홍·2023년 6월 10일

Code Refactoring

목록 보기
3/5

React(Next.js)에서 렌더링 시점은 state의 교체, 부모 컴포넌트의 리렌더링, props의 교체, URL의 이동 등이다. 이 중에서 URL 이동에 따른 렌더링과 useEffect의 dependency에 대해서 다뤄볼 것입니다.

다이나믹 라우팅을 이용한 페이지 이동 중 발생한 문제

: URL 이동 시에 렌더링이 새로 이루어진다고 알고 있었습니다.
그래서 다이나믹 라우팅에서도 새로운 데이터가 들어간 URL로 라우팅이 되면 렌더링이 새로 이루어질 것이라 생각했습니다.
하지만 생각과 다르게 처음 다이나믹 라우팅이 이루어진 화면에서 다른 화면으로 이동하니 처음 화면이 그대로 유지되는 문제가 발생하였습니다.

기능 설명

  1. 각 카테고리별 버튼 클릭
  2. 카테고리 이름을 다이나믹 라우팅을 통해 페이지로 이동
  3. 카테고리 이름을 받아서 카테고리별 리스트를 보여준다.

스터디 URL로 이동 시에는 '스터디' 항목들이 나와야 하는데, 위와 같이 '문화생활' 항목들이 나왔습니다.

문제점 및 해결 방안

: 위를 통해 다이나믹 페이지 내에서는 URL이 이동한 것처럼 보이지만, data만 바뀌었을 뿐 리렌더링이 이루어지지 않았다는 것을 알 수 있게 되었고, 리렌더링이 이루어지게 함으로써 해결할 수 있다.

useEffect dependency 활용

우선 문제 해결을 위해 useEffect Hook의 활용 방법을 알아볼 것입니다.

=> 아래와 같이 useEffect의 dependency를 활용해 리렌더링을 일으킬 수 있습니다.

useEffect(() => {	
}, []);
// dependency가 빈칸이면 해당 컴포넌트가 만들어질 때 처음 한 번 리렌더링이 이루어진다.

const [ex, setEx] = useState(false);

useEffect(() => {
	// [ex]
}, [ex]);
// -> dependency에 ex를 넣어줌으로써 ex의 값이 변할 때마다 리렌더링이 이루어지게 된다.

코드 수정

사이드바

// useRouter를 이용해 라우터 생성
const router = useRouter();

// 버튼 클릭 시 data를 받아 실행
const moveCateIndex = (data: string) => {
    // ${data}를 이용해 다이나믹 라우팅 경로로 이동
    router.push({
        pathname: `/CateIndex/${data}`,
    });
};

// JSX 코드

{cateList.map((item) => (
    <div key={item.id}>
        <button
            type="button"
            onClick={() => moveCateIndex(String(item.name))}
            className={`hover:bg-[#EFF6FF] w-full h-full ${
                item.name === data.data ? "bg-[#EFF6FF]" : ""
            } `}
        >
            <div className="flex py-3.5">
                <p className="pt-1 pl-12">{item.icon}</p>
                <p className="pl-4">{item.name}</p>
            </div>
        </button>
    </div>
))}

다이나믹 페이지 코드(수정 전)

// 라우터 생성
const router = useRouter();

// 사이드바에서 보낸 데이터 저장
const { Category } = router.query;

// 카테고리별 데이터 저장소
const [cateClub, setCateClub] = useState<cateClubInfo[]>([]);

// DB에서 카테고리별 동아리 데이터 받아오기
const selectCategoryClub = async () => {
    try {
        const axiosData = { data: Category };
        const result = await axiosInstance.get("/search/selcectCategoryClub", {
            params: axiosData,
        });

        // 카테고리별 데이터 저장
        setCateClub(result.data);
    } catch (error) {
        console.log(error);
    }
};

// 수정 예정인 코드
useEffect(() => {
    selectCategoryClub();
}, []);

// JSX 코드는 보여줄 동아리 목록 코드이므로 생략하였습니다.
return (
    // JSX 코드
);

수정 후 다이나믹 코드

// DB에서 받아올 데이터를 저장할 곳
const [cateClub, setCateClub] = useState<cateClubInfo[]>([]);

// DB에서 카테고리별 동아리 데이터 받아오기
const selectCategoryClub = async () => {
    try {
        const axiosData = { data: Category };
        const result = await axiosInstance.get("/search/selcectCategoryClub", {
            params: axiosData,
        });

        // 카테고리별 데이터 저장
        setCateClub(result.data);
    } catch (error) {
        console.log(error);
    }
};

// 수정 후
// dependency에 cateClub을 넣어줌으로써 다이나믹 페이지 내에서 data가 바뀔 때마다 리렌더링이
// 이루어질 수 있도록 바꾸어 해결하였다.
useEffect(() => {
    selectCategoryClub();
}, [cateClub]);
  • useEffect dependency에 cateClub을 넣어줌으로써 다이나믹 data가 변화함에 따라 리렌더링을 일으킬 수 있게 변경하여 문제를 해결하였습니다.

느낀 점 및 정리

정리

React에서 URL 이동 시에는 렌더링이 발생한다.
다이나믹 라우팅을 통해 라우팅 페이지로 이동하더라도 렌더링이 발생한다.
하지만 같은 라우팅 페이지 내에서 다이나믹 data가 변경되는 것만으로는 리렌더링이 발생하지 않는다.
그래서 useEffect dependency를 변경해 줌으로써 리렌더링을 발생시킬 수 있다.

느낀 점

처음에 웹 URL의 데이터가 변경됐기에 당연히 페이지가 이동했다고 생각해서 다른 오류가 있을 것이라 생각했고, 렌더링 문제라고는 생각하지 못했습니다.
다음번에 비슷한 현상이 생긴다면 렌더링부터 생각해 볼 수 있을 것 같습니다.

useEffect를 지속적으로 사용해 왔는데, 이론상으로 적혀 있는 내용만으로는 확실히 이해된다는 느낌이 부족했습니다. 이번 해결 과정을 통해서 확실히 이해할 수 있게 되었습니다.

profile
꾸준한 개발자

0개의 댓글