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>
))