🌗

【useRef】React hookが便利すぎる

5 min read

React hookとは..?

React hookはReact16.8から追加された機能で、クラスコンポーネントでしか使用できなかったstateなどのReactの機能を関数コンポーネントで使用できる機能です。
公式ページは以下です。

https://ja.reactjs.org/docs/hooks-intro.html

React hookのAPIについて紹介していこうと思います。
他のReact hookに関するAPIについても解説していますので、そちらもご覧ください。

useRefとは...?

useRef().currentプロパティが渡された引数(initialValue)に初期化されているミュータブルなrefオブジェクトを返します。つまり、要素への参照を行うことができます。返されるオブジェクトはコンポーネントの存在期間全体にわたって存在し続けます。

使い方

  • useRef()に初期値を渡し、refオブジェクトを生成します。
  • currentプロパティにrefオブジェクトの値が保持されます。
const refObject = useRef(initialValue)

const value = refObject.current;

実際にコードで書いてみました。例として、useRefrefオブジェクトを作成したものをref属性(HTML要素)に指定してDOMを参照してみます。

Form1.jsx
import React, { useRef } from 'react';

const Form1 = () => {
    const inputElement = useRef(null);
    const doClick = () => {
        // inputElement.currentで <input type="text" /> を参照できる。
        inputElement.current.focus();
        console.log('inputElement', inputElement.current);
    }

    return (
        <>
            <input ref={ inputElement } type='text' />
            <button onClick={ doClick }>入力欄をフォーカスする</button>
            <div className='line'></div>
        </>
    )
};

export default Form1
App.jsx
import React from 'react';
import { Form1 } from './components/index';

function App() {
  return (
    <div>
      <p>useRefのサンプル1です</p>
      <Form1 />
    </div>
  );
}

export default App;

以下のように動作します。

ボタンクリックで<input type="text">がfocusされます。

useRefとuseStateの挙動の違い

useRefuseStateの挙動の違いをみてみましょう。

useRef使用してDOMを参照する

useRefを使用するとクリックイベントによるstateであるnameが更新された時のみ、コンポーネントの再レンダリングが行われます。

Form2.jsx
import React, { useRef, useState } from 'react';

const Form2 = () => {
    const inputElement = useRef(null);

    const [name, setName] = useState("太郎(※初期の名前です)");

    const doClick = () => {
        setName(inputElement.current.value);
    }

    console.log('再レンダリングされました!!');

    return (
        <>
            <input ref={ inputElement } type='text' />
            <button onClick={ doClick }>名前をセットする</button>
            <p>名前:{ name }</p>
            <div className='line'></div>
        </>
    )
};

export default Form2
App.jsx
import React from 'react';
import { Form2 } from './components/index';

function App() {
  return (
    <div>
      <p>useRefのサンプル2です</p>
      <Form2 />
    </div>
  );
}

export default App;

以下のように動作します。

useState使用してDOMを参照する

useStateを使用するとクリックイベントによるstateであるnameが更新された時とチェンジイベントによるnameの更新の時に、コンポーネントの再レンダリングが行われます。

Form3.jsx
import React, { useState } from 'react';

const Form3 = () => {
    const [inputtedValue, setInputtedValue] = useState("");
    const [name, setName] = useState("太郎(※初期の名前です)");

    const doClick = () => {
        setName(inputtedValue);
    }

    const updataName = (event) => {
        setInputtedValue(event.target.value);
    };

    console.log('再レンダリングされました!!');

    return (
        <>
            <input
                value={inputtedValue}
                onChange={ updataName }
                type='text'
            />
            <button onClick={ doClick }>名前をセットする</button>
            <p>名前:{ name }</p>
            <div className='line'></div>
        </>
    )
};

export default Form3
App.jsx
import React from 'react';
import { Form3 } from './components/index';

function App() {
  return (
    <div>
      <p>useRefのサンプル3です</p>
      <Form3 />
    </div>
  );
}

export default App;

以下のように動作します。

内部に保持している値だけを更新したい、かつコンポーネントの再レンダリングを行いたくない場合にuseRefを利用すると良いですね。

まとめ

今回の記事ではuseRefを紹介しました。次回はuseImperativeHandleを紹介しようと思います。
githubにサンプルコードを載せていますので、気になった方はご覧ください。

https://github.com/Tomoki-webpro/react-hooks-study

参考記事

https://ja.reactjs.org/docs/hooks-reference.html#useref

https://qiita.com/seira/items/0e6a2d835f1afb50544d

Discussion

ログインするとコメントできます