-
React – 3つのref
- 2018年7月25日
- reactjs
React16.3から、refを操作するための新しいAPIが2つ追加されていました。
・createRef
・forwardRef
ref自体頻繁に使用するものではないと思いますが、
例えばinput要素のfocusを操作したいといった場合にrefを指定することがあります。
今回は上記の2者の中でも利用ケースが多いと想定される以前からのrefと
https://reactjs.org/blog/2018/03/29/react-v-16-3.html#createref-api
React16.3より前のバージョンでは、
https://github.com/facebook/react/pull/8333#issuecomment-271648615
によると、Dan Abramov氏が以下のように述べておられる箇所がありました。
createRefを取り上げたいと思います。
以前からのrefとcreateRef
https://reactjs.org/blog/2018/03/29/react-v-16-3.html#createref-api
React16.3より前のバージョンでは、
String Refsstring値でrefを指定する<input ref="hoge" />Callback Refscallback関数でコンポーネント要素と任意に宣言した変数とを紐付ける<input ref={(e) => {this.hoge = e}} />
createRefが加わりました。
Reactのガイドhttps://reactjs.org/docs/refs-and-the-dom.htmlでは、Creating Refsという表記があります。
String Refsはレガシーとされており、いくつか問題があることから、いずれは削除されることが表明されています。
https://reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs
String Refsにはどんな問題があるか?
https://github.com/facebook/react/pull/8333#issuecomment-271648615
によると、Dan Abramov氏が以下のように述べておられる箇所がありました。
1番目の問題としては、
- It requires that React keeps track of currently rendering component (since it can’t guess
this). This makes React a bit slower.- It doesn’t work as most people would expect with the “render callback” pattern (e.g.
<DataGrid renderRow={this.renderRow} />) because the ref would get placed onDataGridfor the above reason.- It is not composable, i.e. if a library puts a ref on the passed child, the user can’t put another ref on it (e.g. #8734). Callback refs are perfectly composable.
String Refsはthisの中身を推測することができないがために、表示されているコンポーネントの状態をReact側で保持させておく必要がある。そのため、若干動作が遅くなる、とのことだそうです。
2番目。String Refsはコンポーネントに直接指定される構造のため、”render callback”パターンのようなことはできないとのこと。
https://github.com/facebook/react/pull/8333#issuecomment-277079817
にあるように、DataGridを例にすると、String RefsはDataGridに指定されるため、MyComponentではなくDataGridを通してアクセスすることになってしまう。
例えばMyComponent上でrefにアクセスする場合、DataTableにrefを付与した上で、this.refs.dataGrid.refs.hogeなどどする必要がある。
Callback Refsだったら直接MyComponent上で保持し、this.hogeのようにアクセスできる。
参考:”render callback”パターン
子コンポーネントのrender時にpropsで定義したcallbackを発火させるパターン。親側で実際の表示内容を定義する。
3番目。Composableでない。様々なコンポーネントを組み合わせてアプリケーションを実装していく際に、String Refsは障害になってしまう。例えば、とあるライブラリがあったとして、ライブラリ内の要素にString Refsをつけていると、ライブラリの利用側で別のrefをつけることができなくなってしまう。
※記事中のissue#8734 -> https://github.com/facebook/react/issues/8734
その点、Callback Refsであれば柔軟に対応可能。
Creating Refs
Callback RefsはComposableなコンポーネント実装を行う際に柔軟に対応できるとのことでした。
一方、16.3でリリースされたCreating RefsはComposableを維持しつつも、よりシンプルに実装できます。
Callback Refsはfunctionとして定義する必要があるのに対し、Creating Refsは以下のようにrefを定義できます。
まとめ
コンポーネント指向に則り再利用性を考慮しながら柔軟にコンポーネントを組み合わせてアプリを迅速に安全に開発するためにCallback RefsやCreating Refsの利用が推奨されています。
また、Callback Refsよりも手軽に利用できるCreating Refsを使うことでちょっとしたref操作であれば簡単に実現できるようになったのではないでしょうか。
参考:
https://leoasis.github.io/posts/2017/03/27/react-patterns-render-callback/
http://developer.medley.jp/entry/2018/02/27/170000
ーー
続 React16.3
createRefと一緒に16.3で追加されたAPIとしてforwardRefがあります。
発展途上のもののようですが、参考として調べてみました。
forwardRef
https://reactjs.org/blog/2018/03/29/react-v-16-3.html#forwardref-api 様々なコンポーネントを組み合わせることにより、一つのアプリケーションを作成するわけですが、 通常のrefだと子のコンポーネントで直接指定した場合、そのコンポーネントのrefになってしまいます。
<Child ref={this.childRef}/> // Childのrefになってしまう
なので、子のコンポーネントのさらに子の要素にrefをつけたい場合、わざわざ別の名前でpropsを指定する必要が生じます。
これを解決するのがforwardRefです。
https://reactjs.org/docs/forwarding-refs.html
この記事を書いた人 : 國田健史
スタッフブログタグ:
AWS bluebird css CSV docker docker compose electron ES6 es2015 Git Heroku ITコンサルティング JavaScript justinmind less MongoDB Node.js php PostgreSQL Private Space Promise React react-router reactjs Salesforce scss Selenium Builder selenium IDE Selenium WebDriver stylus TypeScript VirtualBox VisualStudioCode vue vuejs webpack システム開発プロジェクト セキュリティ ワイヤーフレーム 上流工程 卒FIT 帳票 要件定義 設計 電力小売業界
一覧へ戻る
AWS bluebird css CSV docker docker compose electron ES6 es2015 Git Heroku ITコンサルティング JavaScript justinmind less MongoDB Node.js php PostgreSQL Private Space Promise React react-router reactjs Salesforce scss Selenium Builder selenium IDE Selenium WebDriver stylus TypeScript VirtualBox VisualStudioCode vue vuejs webpack システム開発プロジェクト セキュリティ ワイヤーフレーム 上流工程 卒FIT 帳票 要件定義 設計 電力小売業界