親コンポーネントから子コンポーネントで定義したメソッドなどを公開して実行したりできる機能らしい(Gemini調べ)

ってなわkで使ってみた

src/types/sampple.ts

export interface SampleImperativeHandle {
  update: () => void
}

公開するメソッドとかの雛形を定義する

src/components/Sample.tsx

import { forwardRef, useImperativeHandle, useState } from 'react';
import { type SampleImperativeHandle } from '../types';

const Sample = forwardRef<SampleImperativeHandle>((_props, ref): React.JSX.Element => {
  const [ message, setMessage ] = useState<string | null>(null);

  useImperativeHandle(ref, () => ({
    update(): void {
      setMessage('hoge fuga footer');
    },
  }));

  return (
    <h1>
      {message}
    </h1>
  );
});
Sample.displayName = 'Sample';

export default Sample;

useImperativeHandleで親コンポーネントから渡されるrefを使って公開するメソッドを定義する。あとは親コンポーネントでref経由で公開メソッドをコールできる

src/App.tsx

import { useEffect, useRef } from 'react';
import Sample from './components/Sample';
import type { SampleImperativeHandle } from './types';

const App = (): React.JSX.Element => {
  const ref = useRef<SampleImperativeHandle>(null);

  useEffect(() => {
    const sample = ref.current;

    if (sample === null) {
      return;
    }

    setTimeout(() => {
      sample.update();
    }, 3000);
  }, []);

  return (
    <Sample ref={ref} />
  );
};

export default App;

useRefをuseImperativeHandleの雛形インターフェース(もしくはtype)で型を指定して初期化。んで親コンポーネント(ここではApp)から子コンポーネント(ここではSample)をマウントする際にrefで生成したuseRefのインスタンスを渡す。んでなんだかんだsetTimeoutで遅延されてSampleInperativeHandleで公開されているupdateが実行されるみたいな感じ

実行すると普通に3秒後にhoge fuga foobarって表示されるはず

んまあなんらかの理由により子コンポーネントにあるのを親コンポーネントから操作したい場合とかに使うのかなと