UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【React】ref のフォワーディングについて

ReactのhooksベースでUIの機能を提供するモジュールを作る・使う機会が増えてくると考えられるので、input系の要素を含むコンポーネントforwardRef()でラップしておくのが良さそうという話を聞いた

forwardRefについて理解できていなかったので調べた

ja.reactjs.org

これは基本的にはアプリケーション内のほとんどのコンポーネントで必要ありません。しかし、コンポーネントの種類によっては、特に再利用可能なコンポーネントライブラリにおいては、便利なものとなるかもしれません。

DOM コンポーネントに ref をフォワーディングする

ネイティブの button DOM 要素をレンダーする FancyButton というコンポーネント

function FancyButton(props) {
  return (
    <button className="FancyButton">
      {props.children}
    </button>
  );
}

これを通常の DOM である buttoninput と同様に扱わいたときがある

特に、フォーカス、要素の選択、アニメーションをこなすにはそれら DOM ノードにアクセスすることが避けられないかもしれない

このとき、ref をフォワーディングすると実現ができる

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

これにより下層の button DOM ノードの ref を取得することができ、必要であれば button DOM を直接使うかのように、DOM にアクセスすることができる

上でやっていること

  1. React.createRef を呼び、React ref をつくり、それを ref 変数に代入する
  2. ref<FancyButton ref={ref}> に JSX の属性として指定することで渡す
  3. Reactref を、forwardRef 内の関数(props, ref) => ...の 2 番目の引数として渡す
  4. この引数として受け取った ref<button ref={ref}> に JSX の属性として指定することで渡す
  5. この ref が紐付けられると、ref.current<button> DOM ノードのことを指すようになる