Skip to content negi.log()

カスタムコンポーネントにref propsを作る方法

TL;DR

  • React.forwardRef()にref propsを作りたいカスタムコンポーネントを渡す
  • カスタムコンポーネントはpropsとして受け取ったrefをDOMに渡す

うまくいかない例

下のようなinputタグをラップしたInputコンポーネントを作ったとします。

const Input = () => (
	<div>
		<input />
	</div>
)

このコンポーネントに対して、focusを当てたい場合はどうすればよいでしょうか? inputタグの場合は下のようにReact.createRefで生成したrefをinputのref propsに渡せばよいです。

const Example= () => {
  const ref = React.createRef();
  return (
    <>
      <input ref={ref} />
      <button onClick={() => ref.current?.focus()} />
    </>
  );
}

Inputコンポーネントもpropsにrefを追加して、受け取ったrefをinputタグへ渡せば良さそうですが、実はうまくいきません。 propsにrefを渡してもundefinedになってしまうのです。

// うまくいかない例
const Input = ({ref}) => (
	<div>
		<input ref={ref} />
	</div>
)

const Example= () => {
  const ref = React.createRef();
  return (
    <>
      <input ref={ref} />
      <button onClick={() => ref.current?.focus()} /> // ref.currentはundefinedになってしまう
    </>
  );
}

React.forwardRef を使った方法

ではどうすればよいかというとReact.forwardRefを使います。 React.forwardRefから受け取ったrefを参照したい要素に渡します。 こうすることでカスタムコンポーネントでもJSXの要素と同じようにrefを実装できます。

const Input = React.forwardRef((props, ref) => (
	<div>
		<input ref={ref} />
	</div>
))