Reactを活用したフロントエンド開発においてデータを保持する場合、「useState」や「useReducer」を用いる方法が頭に浮かんでくるかと思います。
しかし、方法としてはもう一つありまして、それが今回ご紹介する「useRef」になります。
本記事では、useStateやuseReducerと同じReact hooksの一つである「useRef」の使い方やuseStateとの違いについて解説させて頂ければと思います。
また、useRefと関連しているhooksについての簡単な紹介と実際に動きとしても理解していけるようにサンプルコードを提供しておりますので、参考にしてもらえたらと思います。
useRefとは
useRefは、useState・useReducerと同じくコンポーネント内でデータを保持するためのReact hooks(関数)になります。また、DOMへの参照も可能であるため、マウント時にDOMの関数を呼び出したりすることが出来ます。
保持しているデータが書き換えられた際に更新されたデータを保持するオブジェクトをrefオブジェクト(ref属性)といい、DOMへアクセスする際にも用います。
言葉だと理解しにくいため、以下の例をご覧ください。useRefと紐づいている要素にて設定されているデータをcurrentプロパティに保持しているため、currentプロパティへアクセスすると値を取得することが出来ます。
useRefとuseState・useReducerの違い
以下のような違いがあります。
- 保持しているデータが更新されても再レンダリングされない (useState・useReducerは、更新時に再レンダリングされる)
- useRefは、データの保持はされるがStateとしては認識されない
- マウント時にDOMの参照が行われ、DOMの関数やプロパティへアクセスが出来る
useRefの使い方
ここでは具体的な使い方と動作を確認していきます。簡単なカウンター機能の作成に加えて、ref属性を設定した要素の現在のデータの取得をみましょう。
カウンター機能の作成
- ①
- ②Appコンポーネントの修正
まずは、src/App.jsを開き、以下のように修正しましょう。
const App = () => { return ( <></> ) } export default App
- ③useRef関数をインポートする
Appコンポーネントの上部に次のコードを記述してください。
import {useRef} from "react"
- ④useRefを定義, JSXを記述
useRefの定義
変数countには、counterの現在のデータ(0)を取得しています。
const counter = useRef(0) let count = counter.current
JSXを記述
+ボタンをクリックした場合は、handleAddClick関数を呼び出し、-ボタンがクリックされるとhandleMinusClick関数を呼び出すようにします。
return ( <> <button onClick={handleAddClick}>+</button> <button onClick={handleMinusClick}>-</button> </> )
- ⑤加算・減算するための関数を定義
+ボタンがクリックされた時は、変数countの値を+1し、-ボタンをクリックされたら-1するようにします。また、加算できるのは100までとし、count内のデータが100の場合は、0にします。
減算の際にも0未満にはならないようにします。
const handleAddClick = () => { console.log(count !== 100 ? count++ : 0) } const handleMinusClick = () => { console.log(count !== 0 ? count-- : 0) }
- ⑥最終コード
import {useRef} from "react" const App = () => { const counter = useRef(0) let count = counter.current const handleAddClick = () => { console.log(count !== 100 ? count++ : 0) } const handleMinusClick = () => { console.log(count !== 0 ? count-- : 0) } return ( <> <button onClick={handleAddClick}>+</button> <button onClick={handleMinusClick}>-</button> </> ) } export default App
- ⑦動作確認
加算
減算
初期値を0より大きい値にしたうえで、確かめてみましょう。
ref属性を設定
手順③までは、カウンター機能の部分と同じになります。
- ④useRefを定義, JSXを記述
useRefの定義
const input = useRef(null)
JSXを記述
useRefと紐づけるinput要素へref属性を設定しています。
return ( <> <input ref={input} /> <button onClick={InputText}>クリック</button> </> )
- ⑤ボタンがクリックされた際に呼ばれる関数を定義
const InputText = () => { console.log(input.current.value) }
- ⑥最終コード
import {useRef} from "react" const App = () => { const input = useRef(null) const InputText = () => { console.log(input.current.value) } return ( <> <input ref={input} /> <button onClick={InputText}>クリック</button> </> ) } export default App
- ⑦動作確認
useImperativeHandleの活用
useStateやuseReducerとの違いの部分で、少し触れましたが、useRefは保持しているデータが更新されても再レンダリングされません。つまりは、更新されたことを知らせないということです。
保持しているデータが更新される際(コンポーネントに対し、refが渡された時)に、親コンポーネントのrefに代入(設定)されるデータを設定する際に使われるのが、useImperativeHandleです。こちらもhooksの一種でありますが、使用することで以下のことが出来ます。
- 子コンポーネントが持つデータを参照
- 子コンポーネント内で定義されている関数を親コンポーネントから呼び出したりすることが可能である
今回は、具体的な使い方は省きますが、useRefと一緒に覚えておくことをオススメします。
まとめ
- useRefは、useState・useReducerと同じくコンポーネント内でデータを保持するためのReact hooksです。useState・useReducerとは違い、保持しているデータの更新時に再レンダリングが発生しません。
- データの保持はされるがStateとしては認識されないため、状態の管理はuseStateかuseReducerを使うようにする
- また、refオブジェクトをコンポーネントへ渡すと、要素のマウント時にDOMの関数などを呼び出すことが可能です。
- useRefと関連しているhooksとしてuseImperativeHandleがある。
コメント