useImperativeHandle는 ref 로 노출되는 handle을 커스텀 할 수 있는 React Hook
useImperativeHandle(ref, createHandle, dependencies?
// Example
import { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
// ...
Parameters
ref : ref는 MyInput 컴포넌트로부터 받은 propcreateHandle: 이 함수는 인자를 받지 않으며 부모 컴포넌트에게 노출하고 싶은 ref handle 객체를 반환한다. ref handle은 무슨 타입이든 가질 수 있고. 일반적으로는 노출하고 싶은 메서드들을 담은 객체를 반환한다.dependencies : 리렌더링 관련 얘기 MEMO
Starting with React 19, ref is available as a prop. In React 18 and earlier, it was necessary to get the ref from forwardRef.
→ React 19부터ref를 prop르로 사용가능, React 18과 그 이전에는forwardRef를 통해 가져왔음
Returns
useImperativeHandle는 undefined를 반환한다.// App.jsx
import { useRef } from 'react';
import MyInput from './MyInput.js';
export default function Form() {
const ref = useRef(null);
function handleClick() {
ref.current.focus();
// This won't work because the DOM node isn't exposed:
// ref.current.style.opacity = 0.5;
}
return (
<form>
<MyInput placeholder="Enter your name" ref={ref} />
<button type="button" onClick={handleClick}>
Edit
</button>
</form>
);
}
// MyInput.jsx
import { useRef, useImperativeHandle } from 'react';
function MyInput({ ref, ...props }) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => {
return {
focus() {
inputRef.current.focus();
},
scrollIntoView() {
inputRef.current.scrollIntoView();
},
};
}, []);
return <input {...props} ref={inputRef} />;
};
export default MyInput;
부모의 ref.current 값을 자식에서 원하는 대로 override 해주는 역할
⚠️주의사항
ef를 남용하지 마세요.
ref는props로 표현할 수 없는 명령형 동작(imperative behavior)에만 사용해야 한다.
→ Ex) 특정 요소로 스크롤하기, 포커스 주기, 애니메이션 트리거, 텍스트 선택 등이 그런 경우입니다.반대로
props로 표현할 수 있는 동작이라면ref를 사용하지 않아야 한다.
→ Ex)Modal컴포넌트에서{ open, close }같은 명령형 핸들을 외부에 노출하는 것보다는
<Modal isOpen={isOpen} />처럼isOpen이라는prop으로 상태를 전달하는 방식이 더 낫다.
이처럼 Effect를 활용하면props를 통해 명령형 동작을 유도할 수 있다.