살면서 우리는 한번씩 부모님께 세뱃돈을 뺏겨본적 한번씩은 있으시잖아요?
마찬가지로 리액트에서도 부모가 자식의 함수를 사용하고 싶은 경우가 생기는데 이때 타입스크립트에서 어떻게 호출하는지 정리하고자 합니다.
아래의 리액트 공식문서에 useImperativeHandle이라는 Hook API가 존재합니다.
공식문서에는 useImperativeHandle는 ref를 사용할 때 부모 컴포넌트에 노출되는 인스턴스 값을 사용자(customizes)한다고 이게 뭔 개소리야.. 설명과 함께 forwardRef를 같이 사용하라고 명시되어있네요.
위의 말을 풀어서 이야기해보면 ref를 사용하면 DOM 노드나 React 요소에 접근이 가능한데 이때 ref를 이용해 부모에서 자식의 DOM 노드나 React 요소에 접근이 가능하니까 커스터마이징된 값(여기서는 자식함수)을 사용할 수 있음을 의미하는것 같습니다.
이게 무슨 소리냐… 싶으실거 같긴한데 예제코드에 설명을 해놓겠습니다.
부모 컴포넌트
const Parents = () => {
// 자식컴포넌트에게 전달할 ref 선언 타입은 자식에서 넘겨줄 함수가 포함되어있는 타입으로
// 현 문서에는 자식컴포넌트에 ChildProps로 선언되어 있습니다.
const childComponentRef = useRef<ChildProps>(null);
// 사실 아래의 value state는 필요없으나 state도 같이 전달하고 싶은 경우가 있기 때문에 같이 전달
const [value, setValue] = useState("value");
const onClick = () => {
// 자식함수 호출
childComponentRef?.current?.testFunc();
}
return(
<div>
<Cildcomponent ref={childComponentRef} value={value}/>
<button onClick={onClick}>자식함수 작동 체크</button>
</div>
)
}
자식 컴포넌트
// 부모에게 보내고자 하는 함수 타입선언
export interface ChildProps {
testFunc: () => void;
}
// props 타입 선언
interface IChild {
value: string;
}
// 자식컴포넌트를 forwardRef<RefType, PropsType>() 형태로 감쌉니다.
const ChildComponent = forwardRef<ChildProps, IChild>(
({value}, ref) => {
const testFunc = () => console.log("나 자식함수야!");
useImperativeHandle(ref, () => ({
// 부모에서 사용하고자 하는 함수이름
testFunc,
}));
return (
<div>
<div>자식 컴포넌트</div>
<div>부모 value props : {value}</div>
</div>
)
});
위의 예제 코드를 실행시켜 보겠습니다. 자식함수 작동 체크 버튼을 누르면 “나 자식함수야!”가 콘솔에 찍히면서 자식함수가 호출이 됨을 확인할 수 있습니다.
예제 코드는 링크에서 테스트할 수 있습니다.