함수형 컴포넌트에서 ref를 prop으로 받을 때 사용하는 함수이다.
React 19버전부터는 forwardRef 없이도 ref를 prop으로 전달 할 수 있다.
현재 forwardRef로 래핑된 컴포넌트의 타입은 ForwardRefExoticComponent이다.
추후 deprecated될 개념이기 때문에 자세히 다루지는 않겠다.
(react 공식문서 : https://ko.react.dev/reference/react/forwardRef)
ref에 직접 내재화된 메서드를 정의 할 수 있는 hook이다.
공식문서에는 아래와 같이 나와있다.
useImperativeHandle의 가장 큰 장점은 인스턴스에 공용 메소드를 내재화 할 수 있다는 것이다.
import { useImperativeHandle } from 'react';
function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... 메서드를 여기에 입력하세요 ...
};
}, []);
// ...
아래와 같은 예시 코드를 보자.
첫번째로 Parent 컴포넌트에 childRef가 존재하고, Child 컴포넌트는 forwardRef + useImperativeHandle 조합으로 인스턴스를 내재화 시켰다.
즉, child 컴포넌트에서 부모컴포넌트에 있는 ref에 직접 focus, clear메소드를 정의했고 이를 다른 컴포넌트에서도 ref를 통해 전달해 사용 할 수 있는 것이다.
단방향의 데이터흐름으로 구성되있는 react에서는 state-lifting을 통해 상위의 컴포넌트에 데이터를 끌어올리게 되는데
아래와 같은 기능을 사용하면, state-lifting을 하지 않고도 하위 컴포넌트에서 내재화 시켜 직접 ref를 재사용하는 방식으로 원하는 메소드를 전달 할 수 있다.
import React, { forwardRef, useImperativeHandle, useRef, Ref } from 'react';
// ChildProps 인터페이스 정의
interface ChildProps {
placeholder?: string;// props로 placeholder 추가
}
// Child 컴포넌트 정의
const Child = forwardRef<HTMLInputElement, ChildProps>((props, ref) => {
const inputRef = useRef<HTMLInputElement>(null);
useImperativeHandle(ref, () => ({
focus: () => {
if (inputRef.current) {
inputRef.current.focus();// input에 포커스 설정
}
},
clear: () => {
if (inputRef.current) {
inputRef.current.value = '';// input 비우기
}
},
}));
return <input ref={inputRef} type="text" placeholder={props.placeholder} />;
});
// Parent 컴포넌트 정의
const Parent: React.FC = () => {
const childRef = useRef<{ focus: () => void; clear: () => void } | null>(null);
const handleFocus = () => {
if (childRef.current) {
childRef.current.focus();// child의 focus 메서드 호출
}
};
const handleClear = () => {
if (childRef.current) {
childRef.current.clear();// child의 clear 메서드 호출
}
};
return (
<div>
<Child ref={childRef} placeholder="Type something..." />
<button onClick={handleFocus}>Focus Input</button>
<button onClick={handleClear}>Clear Input</button>
</div>
);
};
export default Parent;
(https://ko.react.dev/reference/react/useImperativeHandle)
ref)
https://velog.io/@rlwjd31/forwardRef는-왜-쓸까