ref로 노출된 핸들을 사용자 정의할 수 있는 React Hook이다.
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(ref, () => {
return {
// createHandle methods
};
}, []); // optional dependencies
ref
forwardRef에서 두 번째 매개 변수로 받은 ref이다.createHandle
ref 핸들을 return 하는 함수이다.dependencies
createHandle 함수 내에 반응형 값을 사용했다면, 해당 반응형 값이 포함된 배열이다.기본적으로 컴포넌트는 상위 컴포넌트에게 DOM 노드를 노출하지 않는다. 예를 들어, MyInput의 상위 컴포넌트가 <input> DOM 노드에 접근할 수 있도록 하려면 forwardRef로 허용시켜주어야 한다.
import { forwardRef } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
return <input {...props} ref={ref} />;
});위 코드에서 MyInput의 ref는 <input> DOM 노드를 받을 것이다. 하지만 사용자 지정 값을 노출할 수 있다. 노출된 핸들을 사용자 지정하고 싶으면 아래와 같이 코드를 작성하면 된다.
import { forwardRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
useImperativeHandle(
ref,
() => {
return {
// ... your methods ...
};
},
[],
);
return <input {...props} />;
});위 코드에서는 ref에 <input>이 전달되지 않는다. 예를 들어, 전체 <input> DOM 노드를 노출하지 않고 focus나 scrollIntoView 함수를 노출하고 싶다고 가정해보자. 이렇게 하기 위해서는 실제 브라우저 DOM을 별도의 ref에 보관한 다음 useImperativeHandle을 사용하여 부모 컴포넌트에서 호출하려는 메서드만 있는 핸들을 노출하면 된다.
import { forwardRef, useRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
const inputRef = useRef(null);
useImperativeHandle(
ref,
() => {
return {
focus() {
inputRef.current.focus();
},
scrollIntoView() {
inputRef.current.scrollIntoView();
},
};
},
[],
);
return <input {...props} ref={inputRef} />;
});이제 상위 컴포넌트가 MyInput에서 ref를 가져오면 focus랑 scrollIntoView를 호출할 수 있다. 하지만 <input> DOM 노드에 대한 완전한 접근은 할 수 없다.