[React] 컴포넌트 최초 렌더링 시, useEffect 내부 특정 함수 호출을 방지하는 방법

BinaryWoo_dev·2024년 1월 5일
0

React

목록 보기
4/8
post-thumbnail

서론


최근에 사내에서 클래스형으로 작성되어 있는 레거시 코드들을 컴포넌트형으로 변환하면서 전반적인 부분을 리팩터링 및 성능 개선을 진행하고 있다.

그 중에서 클래스형 컴포넌트에 다음과 같이 작성된 부분이 많았다.
(getFilteredData() : 특정 검색 필터가 업데이트 되었을 경우, state update 및 fetch 하는 비동기 핸들러 함수)

this.setState({...nextState}, () => this.getFilteredData())

그래서 컴포넌트형으로 리팩터링 하면서 해당 부분을 useEffect() hook 함수로 대체하려고 다음과 같이 작성했다.

  useEffect(() => {
    getFilteredData(false);
  }, [state.data?.device?.name]);

코드 상으로 봤을 때는 state.data?.device?.name 가 변경 되었을 때 getFilteredData() 함수가 호출되어 해결된 것 같았지만 가장 큰 문제가 있다. 그 문제는 바로

⚠️ 최초 렌더링 시, getFilteredData() 함수로 최초 1회 호출 된다.

이렇게 되면, 최초에 주요 data들을 서버로부터 fetch 하여 state update 하는 핸들러 함수와 setState 작업이 충돌하여 가장 마지막 setState 작업만 실행되고 같이 업데이트 되어야할 나머지 state들이 무시된다는 것.

그래서, 방법을 찾아보다가 아주 깔끔하고 간편한 해결 방법을 찾았다.

본론


useRef() 을 이용하기

그 방법은 바로 useRef() hook 함수를 사용하는 것이다. 예시 코드는 다음과 같다.

import { useRef, useEffect } from 'react';

const Table = () => {
	const isInitialRender = useRef(true);
  
   useEffect(() => {
     if (isInitialRender.current) isInitialRender.current = false;
     else getFilteredData(false);
  }, [state.data?.device?.name]);
}

코드만 봐도 부연 설명이 필요없을 정도로 짧고 간단하지만, 설명하자면 다음과 같다.

  1. useRef hook 함수를 사용하여 isInitialRender 라는 변수로 참조를 생성하며,이 참조는 초기값으로 true를 설정한다.
  2. useEffect 내부에서 isInitialRender.current 값을 확인한다.
    • true인 경우 함수 호출을 건너뛰고 참조를 false로 업데이트하면 리렌더링 시, 해당 렌더링 유형이 최초 렌더링이 아님을 전달할 수 있다.
    • Table 컴포넌트 리렌더링 시, !isInitialRender: true 로 인해 if문 내에 선언되어있는 기능 함수 getFilteredData() 가 정상적으로 호출된다.

결론


이번이 아니라도 흔하게 마주할 수 있는 상황이기 때문에 해당 방법을 잘 숙지하여 좀 더 생산성을 향상시킬 수 있도록 해야겠다.

이 글이 누군가에게 꼭 도움이 되기를 바란다. 화이팅 🙂

profile
매일 0.1%씩 성장하는 Junior Web Front-end Developer 💻🔥

0개의 댓글