Devlog

[React] useEffect 첫 렌더링 때 작동 못하게 하기 본문

FrontEnd/React

[React] useEffect 첫 렌더링 때 작동 못하게 하기

recoma 2024. 3. 31. 18:47
728x90

useEffect를 사용하개 되면 state값 (useState로 선언된 변수들)이 바뀔 대 마다 이에 대한 대응을 할 수 있게 됩니다.

예를 들어 장바구니에서 내가 구매하기 위해 선택한 항목들을 다시 프로그램을 켜도 유지하고 싶다고 한다면, 항목이 변경될 때마다 항목 리스트를 업데이트 하는 API를 호출해야 합니다. 이때 useEffect를 사용하게 되면 해당 요구사항을 해결할 수 있겠죠

const [selectedItems, setSelectedItems] = useState([]);

useEffect(() => {
	// 대충 항목리스트 업데이트하는 API 호출
	axios.post("/url", data=selectedItems...)
}, [selectedItems]);

 

 

또한 useEffect는 state값이 변경되는 경우 말고도 처음 웹이 렌더링이 되었을 때도 작동이 되는데, 이를 이용해 state 변수 리스트를 가지는 deps라는 인자값을 빈배열로 선언하게 되면, useEffect에 등록된 콜백 함수는 오로지 첫 렌더링 때만 작동하게 됩니다.이를 이용해 오직 한번만 실행해야 하는 로직들을 작성할때 자주 사용되곤 합니다. 예를 들어 보통 서버에서 데이터를 가져오는 프로세스는 오직 한번만 작동해야 하는 경우가 많기 때문에 해당 방법을 사용하게 됩니다.

useEffect(() => {
	// 대충 서버로부터 데이터를 가져오는 로직
}, []); // deps는 빈배열

 

 

하지만 가끔씩 이 useEffect를 처음 렌더링 할 때만 적용이 되지 않기를 바랄 때도 있습니다.

useEffect의 콜백 함수에서 처음 렌더링 했을 때 로직이 작동되지 않도록 분기점을 만드는 전략을 세울 수 있지만, 여러군데에서 사용할 경우 해당 기능을 모듈화할 필요가 있습니다.

const useDidMountEffect = (func, deps) => {
    const didMount = useRef<boolean>(false);

    useEffect(() => {
        if (didMount.current) {
            func();
        } else {
            didMount.current = true;
        }
    }, deps);
}

// 활용
useDidMountEffect(() => {
	// 대충 뭔갈 작업하는 로직
}, []);

didMount를 false로 초기화를 했습니다. 즉, 처음 렌더링 할 때는 didMount가 false이기 때문에 콜백함수 func()를 실행하지 않고 didMount를 true로 전환합니다. 그리고 다음 렌더링 때는 didMount가 false가 아닌 true이므로 이때 콜백함수를 실행합니다.

didMount는 useState가 아닌 useRef로 선언이 되었는데, useRef는 useState와 달리 값이 변경되었다고 해서 Rerendering을 하지 않습니다. 만약에 didMount를 useState로 선언을 했다면, didMount.current = true 시점에서 개발자가 원하지 않음에도 불구하고 Rerendering 발생을 했을 것입니다. 하지만 useRef를 사용함으로써 그런 일은 일어나지 않습니다.

이렇게 해서 첫 렌더링시 useEffect 콜백 함수가 작동하지 않게 할 수 있게 되었습니다.

 

틀린 부분이 있으면 지적 부탁드려요!

 

 

출처: https://velog.io/@dlruddms5619/React-useEffect-%EC%B2%AB-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%8B%9C-%ED%95%A8%EC%88%98-%EC%8B%A4%ED%96%89-%EB%A7%89%EA%B8%B0

728x90
반응형