useImperativeHandle
とは
親コンポーネントに対して子コンポーネントの特定のインスタンス値やメソッドを公開するために使用されます。これにより、親コンポーネントは子コンポーネントの内部状態に直接アクセスすることなく、必要な機能だけを利用することができます。
使用方法
useImperativeHandle(ref, createHandle, [dependencies])
-
ref
: 親コンポーネントから渡されたref
オブジェクト -
createHandle
: 公開するハンドル(オブジェクト)を返す関数 -
[dependencies]
: ハンドルの再生成を制御する依存関係の配列
カスタムメソッドを公開する
以下の例では、MyInput
コンポーネントがfocus
とscrollIntoView
のメソッドを親コンポーネントに公開します。
MyInput.jsx
import { useRef, useImperativeHandle } from 'react';
function MyInput(props, ref) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus() {
inputRef.current.focus();
},
scrollIntoView() {
inputRef.current.scrollIntoView();
},
}), []);
return <input ref={inputRef} />;
}
export default React.forwardRef(MyInput);
-
useRef
を使ってinput
要素への参照を保持します -
useImperativeHandle
を使用して、親コンポーネントに公開するメソッドを定義します。この例では、focus
とscrollIntoView
の2つのメソッドを公開しています -
React.forwardRef
を使用して、親から渡されたref
を転送します
Form.jsx
import { useRef } from 'react';
import MyInput from './MyInput.js';
export default function Form() {
const ref = useRef(null);
function handleClick() {
ref.current.focus();
// 以下の操作は許可されていないため動作しない:
// ref.current.style.opacity = 0.5;
}
return (
<form>
<MyInput ref={ref} />
<button type="button" onClick={handleClick}>
編集
</button>
</form>
);
}
-
useRef
を使ってMyInput
コンポーネントへの参照を作成します - ボタンがクリックされると、
ref.current.focus()
を呼び出して、MyInput
内のinput
要素にフォーカスを当てます - 他のプロパティやメソッドは公開されていないため、直接アクセスすることはできません
なお、公開するメソッドは、DOM メソッドと正確に一致する必要はありません。自作のメソッドを公開することもできます。