Closed7

forwardRefって何なんだっけ?

terrierscriptterrierscript
terrierscriptterrierscript

結論

  • refはそもそも下記のような動きをする
    • DOMならdomエレメント
    • それ以外ならクラスインスタンス
    • インスタンスを持たないものにrefしてもコケるだけ
  • なのでFunctional Componentにはrefをそのまま渡せない
  • forwardRefによりスキップして下位コンポーネントに渡せるようになる
    • これは単なる便利関数ではなく、Reactの内部で特殊に処理されている
  • forwardRefを使いたくなければ_refみたいに名前よけする
terrierscriptterrierscript

そもそもとして自前したコンポーネントに対してrefを渡すとその時点で怒られる

const ref = useRef()
<SomeComponent ref={ref} /> // refが取れないエラーが発生

なので慣例的に別な名前をつけてrefを渡したりすることがあった

const SomeComponent = ({ _ref }) => {
  return <div id="non-forarded" ref={_ref}>non-forwarded</div>
}

const ref = useRef()
<SomeComponent _ref={ref} /> // これならOK

で、これをショートハンド化(?)するのがforwardRef

const Forwarded = forwardRef<HTMLDivElement>((props, ref) => {
  return <div id="forarded" ref={ref}>forwarded</div>
})

const ref = useRef()
<SomeComponent ref={ref} /> // OK
terrierscriptterrierscript

なんでカスタムコンポーネントにref出来ないんだっけ?

HTML 要素に対して ref 属性が使用されている場合、React.createRef() を使ってコンストラクタ内で作成された ref は、その current プロパティとして根底にある DOM 要素を受け取ります

ref 属性がカスタムクラスコンポーネントで使用されるとき、ref オブジェクトはコンポーネントのマウントされたインスタンスを current として受け取ります

関数コンポーネント (function components) には ref 属性を使用してはいけません。なぜなら、関数コンポーネントはインスタンスを持たないからです

そうだった。インスタンスを取るのだからFCは取れないんだった。

terrierscriptterrierscript

Class CompoenntにRefつけると何起きるんだっけ?

class NonForwardedClass extends React.Component {
  render() {
   // ↓このthis.props.refは取れない
    return <div id="non-forarded-class" ref={this.props.ref}>non-forwarded-class</div>
  }
}

<NonForwardedClass ref={ref3} />
// ↑このref3は {current: NonForwardedClass}  が取れる
terrierscriptterrierscript

ソースをまさぐる

ということで思ったより特殊なことされてるっぽい

このスクラップは2021/05/13にクローズされました