react

useImperativeHandle는 무엇인가?

weaklion 2025. 10. 16. 17:59

최근 리액트를 이용해 간단한 사이드 프로젝트를 진행하고 있습니다. 

 

프론트엔드 개발자로써 사실 리액트보다 vue를 쓰는 기간이 더 많아서, 아직 react에 적응하는 기간인데

사용하면서 가장 곤란했던 부분이 있습니다. 

 

바로 vue는 양방향의 데이터바인딩을 지원하지만, react는 오직 단방향만 지원한다는 점입니다. 

오늘은 이 부분을 단적으로 보여주는 react의 useImperativeHandle에 대해서 적어보도록 하겠습니다.

 

useImperativeHandle

useImperativeHandle은 ref를 통해 부모 컴포넌트에 노출할 인스턴스 값을 사용자 커스텀할 수 있는 기능입니다. 이를 통해 부모 컴포넌트는 자식 컴포넌트에 원하는 인스턴스를 호출할 수있습니다. 주로 fowardRef와 같이 사용합니다.

 

const CustomComponent = forwardRef((props, ref) => {
	//...

  useImperativeHandle(ref, () => ({
    handleCustomLog: (type, value) => {
      console.log('custom log')
    }
  }));

  // ... 
});
const ParentComponent = () => {
  const customRef = useRef(null);

  const handleLog = () => {
    if (customRef.current) {
      customRef.current.handleCustomLog();

    }
  };

  return (
    <CustomComponent
      ref={customRef}
      /..
    />
  );
};

 

react 19 버전을 기준으로 forwardRef는 삭제 됐으니, ref로 사용하셔도 무방합니다.

어쨌든 코드를 작성해보니 vue의 defineExpose()와 유사합니다. vue에서는 defineExpose()를 통한 양방향의 데이터바인딩을 권장하고 있지만 , react에서는 권장하지 않는 방식입니다.

 

주요 이유는 아래와 같습니다.

  1. 명령형(Imperative) 코드를 조장함
    • React는 "무엇을(what)" 렌더링할지 선언하는 방식을 지향하는데, useImperativeHandle은 "어떻게(how)" 동작할지 명령하는 방식입니다.
    • 부모가 자식의 메서드를 직접 호출하는 것은 명령형 패턴입니다.
  2. 컴포넌트 캡슐화를 깨뜨림
    • 자식 컴포넌트의 내부 구현을 부모에게 노출하게 되어, 컴포넌트의 독립성이 약화됩니다.
    • 자식의 내부 구조를 변경하면 부모 코드도 함께 수정해야 할 수 있습니다.
  3. 데이터 흐름을 추적하기 어려움
    • props를 통한 단방향 흐름이 아니라 ref를 통한 직접 제어이기 때문에, 코드를 읽을 때 데이터 흐름을 파악하기 힘듭니다.
  4. 테스트와 유지보수가 어려움
    • ref를 통한 직접 조작은 테스트 코드 작성이 복잡해지고, 디버깅도 어렵습니다.

그럼에도 사용해야 한다면 사용하는 게 맞습니다. 저는 dom 제어를 위해서 사용할 것 같습니다.

 

'react' 카테고리의 다른 글

react로 그림판을 만든 뒤 후기 [0]  (0) 2025.12.10
[react] setState에 관하여.  (0) 2019.03.24
리액트 router의 activeClassname에 관한 팁.  (0) 2019.02.25