[React] useEffect의 clean-up 함수 : 컴포넌트 unmount시 모달 isOpen값 false로 변경하기

sjoleee·2022년 9월 16일
2

문제 상황

프로젝트에서 게시물 삭제 기능을 구현하며 겪은 문제다.
만약 모달이 켜져있는 상태에서 페이지를 이동했다가 다시 진입할 경우 모달이 켜진 상태인 버그가 발생했다.
모달이 나타나고 사라지는 것을 isModalOpen이라는 boolean으로 조작하고 있었는데, 이를 Recoil로 전역 관리하는 바람에 발생한 문제였다.

애초에 전역관리 하지 않았으면 됐을 문제이긴 하지만, 가독성을 위해 컴포넌트를 계속 분리하다 보니 props drilling이 일어나는 것을 막기 위해 전역으로 관리하게 되었다.

해결 방법

다른 페이지에 진입하면 isModalOpen을 false로 업데이트

모든 페이지의 렌더링 시점에 setIsModalOpen(false)를 실행하는 것이다.
처음 이 방법을 생각하고 확실한 방법이긴 하겠다는 생각을 했다.

다만, 페이지가 추가된다면 잊지 않고 해당 페이지에 setIsModalOpen(false)를 작성해야만 하는 문제가 있었다.
혼자 개발한다면 어떻게든 기억해내고, 깜빡해도 금방 추가할 수 있겠지만 협업 프로젝트이기 때문에 동일한 문제를 팀원이 겪게 된다면 대응하기 어렵겠다고 생각했다.

또한, 원하는 바는 이루겠지만 절대 좋은 코드는 아니라는 생각이 들었다.
따라서 해당 방법은 고려하지 않고, 다른 방법을 조사했다.

모달의 언마운트 시점에 useEffect의 cleanup 함수 활용

여러 방법을 고민하다가 다른 페이지에 진입이 아니라, 기존 페이지에서 이탈하는 것을 감지할 수 있지 않을까? 라고 생각하게 되었다.
관련된 방법 중에서 가장 효율적인 방법이 무엇일까 고민하게 되었고, 컴포넌트의 언마운트 시점 이라는 키워드로 조사하여 useEffectcleanup 함수를 사용하면 되겠다는 결론을 얻었다.

당시 나는 useEffect를 이렇게만 생각했다.

  • (마운트)컴포넌트가 렌더링 될 때 작업을 실행한다.
  • (업데이트)deps를 통해 특정 값이 변화할때마다 실행할 수도 있다.

그런데, 하나가 더 있었던 것이다.

  • (언마운트)컴포넌트가 사라질 때 작업을 실행한다.

useEffect 정리

React 공식문서는 이렇게 말하고 있다.

React의 class 생명주기 메서드에 친숙하다면, useEffect Hook을 componentDidMount와 componentDidUpdate, componentWillUnmount가 합쳐진 것으로 생각해도 좋습니다.

즉, useEffect 자체가 함수형 컴포넌트에서도 클래스 컴포넌트의 생명주기 메서드를 사용할 수 있게 해주는 것이다.
따라서 useEffect에도 componentWillUnmount 메서드에 해당하는 기능이 있는데, 이것이 바로 clean-up 함수이다.

clean-up

clean-up 함수는 useEffect Hook 내에서 return되는 함수이다.
컴포넌트가 사라질 때(unmount 시점), 특정 값이 변경되기 직전(deps update 직전)에 실행할 작업을 지정할 수 있다.

  useEffect(() => {
    // mount 시점, deps update 시점에 실행할 작업 (componentDidMount)
    return () => {
      //unmount 시점, deps update 직전에 실행할 작업 (componentWillUnmount)
    };
  }, [deps]);

문제 해결

// ArticleDeleteModal.jsx

  const handleModal = (e) => {
    setDeleteArticleId(""); // 삭제하고자 하는 게시물의 ID값을 빈 문자열로 업데이트
    setIsDeleteModalOpen(false); // isDeleteModalOpen을 false로 업데이트
  };

  useEffect(() => {
    return () => handleModal(); //언마운트 시점에 handleModal 함수 실행
  }, []);

느낀 점

컴포넌트 생명주기를 좀 더 제대로 이해하고, 개발할때 사용해야겠다는 생각이 들었다.
기능 구현하면서 필요한 부분만을 익힌 느낌이 든다.
더 넓고 깊게 공부해서 다양한 상황에 적용할 수 있는 실력을 키우고 싶다!!

참고한 글
https://react.vlpt.us/basic/16-useEffect.html
https://ko.reactjs.org/docs/hooks-effect.html
https://ko.reactjs.org/docs/hooks-reference.html#useeffect

profile
상조의 개발일지

0개의 댓글