親コンポーネントがrefを通じてアクセスできるメソッドをカスタマイズする。forwardRefと組み合わせて使う。
useImperativeHandle(ref, createHandle, dependencies?)
interface InputHandle {
focus: () => void;
clear: () => void;
}
const Input = forwardRef<InputHandle, Props>((props, ref) => {
useImperativeHandle(ref, () => ({ focus, clear }));
...
});import { useRef, useImperativeHandle, forwardRef } from 'react';
interface InputHandle {
focus: () => void;
clear: () => void;
getValue: () => string;
}
const CustomInput = forwardRef<InputHandle, { placeholder?: string }>(
({ placeholder }, ref) => {
const inputRef = useRef<HTMLInputElement>(null);
useImperativeHandle(ref, () => ({
focus: () => inputRef.current?.focus(),
clear: () => { if (inputRef.current) inputRef.current.value = ''; },
getValue: () => inputRef.current?.value ?? '',
}));
return <input ref={inputRef} placeholder={placeholder} />;
}
);
// 親コンポーネントから使う
function Parent() {
const inputRef = useRef<InputHandle>(null);
return (
<>
<CustomInput ref={inputRef} placeholder="入力..." />
<button onClick={() => inputRef.current?.focus()}>フォーカス</button>
<button onClick={() => inputRef.current?.clear()}>クリア</button>
</>
);
}useImperativeHandleは命令的なAPIが本当に必要な場合(アニメーション・フォーカス管理等)に限定して使う。通常は状態やpropsで制御する方がReactらしい設計。