토스트 구현에 let 대신 useRef 쓰기

forestream·2024년 3월 9일
0

프로젝트 진행 중 URL 복사 시 복사되었다는 토스트 구현 시도

/* css */
@keyframes PopUp {
  0% {
    bottom: -8rem;
  }
  5% {
    bottom: 9rem;
  }
  95% {
    bottom: 9rem;
  }
  100% {
    bottom: -8rem;
  }
}

.ToastBox {
...
  position: fixed;
  bottom: -8rem;
  left: 50%;
  transform: translate(-50%, 0);
...
  animation: PopUp 5s ease 0s 1;
}
...

let 변수 선언

/* URL 복사 성공 토스트 */
  let copyToastUp;
  const showCopyToast = () => {
    clearTimeout(copyToastUp);
    setCopiedToastUp(true);
    copyToastUp = setTimeout(setCopiedToastUp, 5000, false);
  };

let으로 변수를 하나 만들고
URL이 복사될 때마다 showCopyToast 함수가 실행되도록 작성.
처음에 변수에 있던 타이머를 지우고
토스트의 상태를 참으로 바꾼 후
5초 후 거짓으로 바꿀 타이머(의 리턴값인 id)를 변수에 할당.

이 경우

  • 컴포넌트가 렌더될 때마다 copyToastUp이라는 변수가 매번 선언되어야 한다.
  • URL 복사 후 페이지를 전환한다거나 할 경우 copyToastUp에 등록된 5초 타이머가 지워지지 않고 남아 있게 된다.

그 후 멘토님의 리뷰를 반영하여 수정했다.

useRef 사용

/* URL 복사 성공 토스트 */
  const toastUp = useRef();

  useEffect(() => {
    if (copiedToastUp) {
      toastUp.current = setTimeout(setCopiedToastUp, 5000, false);
    }

    return () => {
      clearTimeout(toastUp.current);
    };
  }, [copiedToastUp]);

  const showCopyToast = () => {
    setCopiedToastUp(true);
  };

타이머를 useRef 객체가 담긴 상수의 current 프로퍼티에 할당.
useEffect를 사용하여 컴포넌트가 업데이트나 언마운트 될 때마다 타이머 삭제 함수를 실행.
디펜던시 리스트로 토스트의 스테이트를 전달한다.
useEffect 내부에 토스트 스테이트에 따라 실행할 코드를 작성.

이렇게 하면

  • 처음 컴포넌트가 마운트 될 때 copiedToastUp의 스테이트 값은 거짓이므로 조건문을 실행하지 않고 바로 클리어 함수를 등록.
  • URL 복사 시 스테이트가 변경되면서 컴포넌트 리렌더
    - 단축 평가({copiedToastUp && <Toast />})에 따라 토스트 컴포넌트 렌더 (화면에 나타남)
    - useEffect 내부 클리어 함수 실행(지워지는 타이머 없음)
    - 5초 타이머 등록
    - 타이머를 지울 클리어 함수 등록
    - 5초 후 토스트 컴포넌트 언마운트 ...

등등의 절차를 거치며 상태 관리가 더욱 용이해지게 됐다.

0개의 댓글