連載目次 : React入門
前回の記事 : useMemoとuseCallback / React Hooks
次回の記事 : useReducer/ React Hooks
今回はReact Hooksでfunctionコンポーネントの再描画を抑制することができるuseRef
について解説をします。
要素の参照
classコンポーネント利用時にはref属性を利用して要素を参照することができましたが、functionコンポーネントではuseRef
を利用して要素の参照を行います。
次のサンプルではuseRef
でinput要素への参照オブジェクトを作成してref属性
でinput要素と関連付けを行っています。button要素がクリックされた際にinputEl.current
でinput要素のアクセスすることができます。
function App() {
const inputEl = useRef(null)
const [text,changeText] = useState("")
const handleClick = useCallback(()=>{
changeText(inputEl.current.value)
},[])
return (
<>
<p>text : {text}</p>
<input ref={inputEl} type="text" />
<button onClick={handleClick}>set text</button>
</>
)
}
同様のコードをuseRef
を利用せずにuseStateを利用して記述した場合は以下のようになります。
function App() {
const [tmpText,changeTmpText] = useState("")
const [text,changeText] = useState("")
const handleClick = useCallback(()=>{
changeText(tmpText)
},[tmpText])
return (
<>
<p>text : {text}</p>
<input
value={tmpText}
onChange={e => changeTmpText(e.target.value)}
type="text"
/>
<button onClick={handleClick}>set text</button>
</>
)
}
入力中の文字列をステート「tmpText」に格納しておきボタンが押されたタイミングでステート「text」に代入することで同様の挙動を実装することができます。
useRef
を利用するかどうかの大きな違いはコンポーネントの再描画が発生するかどうかです。
useRef
を利用していないパターンではステート「tmpText」とステート「text」の更新時にコンポーネントの再描画が発生しますが、useRef
を利用しているパターンではステート「text」の更新時にのみコンポーネントの再描画が発生します。
値の参照
Classコンポーネント時のref属性の利用方法や先程解説した要素へのアクセス方法からuseRef
はDOMへのアクセスを保存するもののように思われがちですが、Classのインスタンス変数と同様な利用方法が可能です。
次のサンプルではuseRef
を利用して変数「count」を作成してadd coutnボタンが押された際に1づつ加算していき、show logボタンが押されたタイミングでConsole上に現在の現在のカウントを表示することができるスクリプトです。
function App() {
const count = useRef(0);
const addCount = useCallback(()=>{
count.current += 1
},[])
const showLog = useCallback(()=>{
console.log(count.current)
},[])
return (
<>
<button onClick={addCount}>add count</button>
<button onClick={showLog}>show log</button>
</>
)
}
変数の初期値はuseRef
の引数に指定ができ今回の初期値は0にしています。変数はcurrent
プロパティに格納されているのでcount.current
に対して変更を行うことができ、呼び出し時も直接count.current
を呼び出します。
これをuseState
を利用して記述する場合は以下のようになります。
function App() {
const [count, changeCount] = useState(0);
const addCount = useCallback(()=>{
changeCount(prevCount => prevCount+1)
},[])
const showLog = useCallback(()=>{
console.log(count)
},[count])
return (
<>
<button onClick={addCount}>add count</button>
<button onClick={showLog}>show log</button>
</>
)
}
こちらも大きな違いはコンポーネントの再描画が発生するかどうかです。useState
を利用している場合はステートcountの値に変更が発生する度にコンポーネントの再描画が発生しますがuseRef
を利用している場合はコンポーネントの再描画が発生しません。
コンポーネントの再描画や子コンポーネントの再描画は行いたくないが内部の値のみ更新したい場合などでは値をuseState
で定義するのではなくuseRef
を利用するのがよいでしょう。
次回は複数のステートをまとめて制御できるuseReducer
について解説をおこないます。
連載目次 : React入門
前回の記事 : useMemoとuseCallback / React Hooks
次回の記事 : useReducer/ React Hooks
【告知】弊社のメンバーが執筆した書籍が発売されました!
弊社のメンバーが執筆した『初心者からちゃんとしたプロになる JavaScript基礎入門』が発売されました! JavaScriptの基礎からVue.jsまでをカバーしており、初学者から基本の復習をしたい方におすすめの1冊です。
フロントエンドエンジニア積極採用中
株式会社トゥーアールでは現在フロントエンドエンジニア積極的に採用中です!
興味がある人は採用ページをチェック!!