2018/04/05更新

[フロントエンド] React.jsでDOM要素にアクセスする(refの利用)

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
Reactなどの仮想DOMを扱うライブラリでは、直接HTML要素にアクセスする機会は少ないですが、でも時々はアクセスしたい場合があります。React流にどのようにDOMにアクセスするのか、ブログに書きたいと思います。



目次




対象のReactバージョン

このブログでは、React.jsのv16.3.0をベースに記載しています。フロントエンドは進化が早いので、適宜読み替えてください。



何がしたいのか

Webアプリを作っていると、DOM要素にアクセスして値を取得したいという場合があります。例えば以下のようなinputがあるとします。
<input type="text" name="name"/>
このDOMにアクセスしたい場合、(Reactではない普通のJSでは)以下のようにアクセスします。
let input = document.querySelector('input')
let value = input.value
これは普通のWebの実装ですが、Reactでは流儀違反です(正しく値は取得できますが、直接DOMにアクセスはしない)。Reactではどのようにするべきか、を説明したいと思います。



refを用いてDOMにアクセスする

React.jsではrefという要素を用いて、DOMにアクセスできます。
以下のように実装します。
<input
    type="email"
    ref={ input => { this.emailInput = input }}
    placeholder="E-mail address"/>
refには関数を指定します。その関数の引数には、DOMへの参照が渡され、それを利用してDOMへアクセスします。ここではemailのinput要素を受け取り、this.emailInputに代入しています。

そして、そのinputから値を取得したい場合には、以下のように実装します。
// <input type="email"/> から値を取得
let emailAddress = this.emailInput.value
このようにReactでは、refを用いることで、DOMにアクセスすることが可能です。



コードの全体像

コードの全体像はこちらです。理解の手助けになれば幸いです。
import React, { Component } from 'react'

class MyComponent extends Component {

    onClick() {
        // DOM要素から値を抽出する.
        let emailAddress = this.emailInput.value
        console.log(emailAddress)
    }

    render() {
        return (
            <div>
                <input
                    type="email"
                    ref={ input => { this.emailInput = input }}
                    placeholder="E-mail address"/>
                <div
                    onClick={this.onLogin}>
                        Login
                </div>
            </div>
        );
    }
}



参考1:refは非推奨

Reactの以前のバージョンでは、refではなく、refsでDOM要素へのアクセスを記載していました。
<!-- 現在は非推奨 -->
<input type="text" refs="name"/>
これ執筆時点(2018年4月)はドキュメント上で非推奨ですが、近い将来プログラム的にも非推奨(その後に廃止)になるようです。
理由としては、いくつかの問題があり、例えばReactの内部実装が複雑になったり、速度が少し遅くなったりすることが問題のようです。



参考2:input要素の値を取得する方法

今回はrefの説明でしたが、onChangeを用いる実装の方がよりReactらしい実装かなと思います。以下の公式ドキュメント(Forms - React)を参照ください。



最後に

Reactの実装でつまづくポイントはいっぱいありますが、今回のようなTipsを覚えておくと実装が効率的にできていいですよね。今後も色々と書きたいと思います。

最後になりますが本ブログでは、フロントエンド、Swift、PHP、Node.js、Linux、Python、Java、インフラ、Go言語、機械学習、などの技術トピックを発信をしていきます。「プログラミングで困ったその時の、解決の糸口に!」そんな目標でブログを書き続けています。ぜひ、本ブログのRSSTwitterをフォローして貰えたら嬉しいです ^ ^

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

[取り組み] フロントエンドでコーディングスピードをアップさせる6つの方法!と思って書いてたら30個も書いちゃった。
[フロントエンド] フロントエンドの入社試験99問!難しいですよ〜w。
[フロントエンド] Webページを表示するテストの際に、通信速度を3Gに制限して表示してみよう
[フロントエンド] スマホ実機でのデバッグ手段を増やす!Macのプロキシを利用して、通信内容を確認する。
[フロントエンド] Chrome 35 Beta の変更点。Touch制御、新しいJavaScript機能、プレフィックスなしのShadowDOM
[フロントエンド]複数アカウントでのテストには、Chromeのユーザー管理を使って、Cookieを切り替えると便利
[フロントエンド] Chrome36βが出た。変更点など。element.animate、HTML Imports、Object.observe、他。
RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。