[React Hook] useImperativeHandle, forwardRef

bbio3o·2021년 3월 22일
0

React

목록 보기
5/5
post-thumbnail

리액트에서 ref를 이용하는 것은 직접적으로 DOM을 다루어야 하는 상황이 아닌 이상 권장되지는 않지만 ref를 이용하면서 유용하게 쓰일 수 있습니다.

useImperativeHandle은 ref를 사용할 때 부모 컴포넌트에 노출되는 인스턴스 값을 사용자화(customizes)합니다. 항상 그렇듯이, 대부분의 경우 ref를 사용한 명령형 코드는 피해야 합니다. useImperativeHandle는 forwardRef와 더불어 사용하세요.
리액트 공식문서


useImperativeHandle(ref, CB)

  • 자식 컴포넌트의 메소드를 부모에서 쓸 수 있다.
  • forwardRef와 함께 쓰인다.

import React, {
  useState,
  useEffect,
  forwardRef,
  useImperativeHandle,
} from 'react';

const Timer = forwardRef(({ onTimeOver }, ref) => {
  const [min, setMin] = useState(0);
  const [sec, setSec] = useState(0);
  const [isRunning, setIsRunning] = useState(false);

  useImperativeHandle(ref, () => ({
    startTimer(minutes, seconds) {
      setMin(minutes);
      setSec(seconds);
      setIsRunning(true);
    },
    stopTimer() {
      setMin(0);
      setSec(0);
      setIsRunning(false);
    },
  }));

  useEffect(() => {
    if (!isRunning) {
      return null;
    }

    const timer = setInterval(() => {
      if (sec < 60 && sec > 0) {
        setSec(sec - 1);
      } else if (sec === 0 && min > 0) {
        setMin(min - 1);
        setSec(59);
      } else {
        setIsRunning(false);
        onTimeOver();
      }
    }, 1000);

    return () => {
      clearInterval(timer);
    };
  }, [min, sec, onTimeOver, isRunning]);

  return (
    <div>
      {isRunning && (
        <span>
          {min} : {sec}
        </span>
      )}
    </div>
  );
});

export default Timer;

참조

profile
그림도 그리는 개발자 🎨👩‍💻

0개의 댓글