#React hooksとは
React 16.8 で追加された新機能です。
クラスを書かなくても、 state
などのReactの機能を、関数コンポーネントでシンプルに扱えるようになりました。
- React hooksを基礎から理解する (useState編)
- React hooksを基礎から理解する (useEffect編)
- React hooksを基礎から理解する (useContext編)
- React hooksを基礎から理解する (useReducer編)
- React hooksを基礎から理解する (useCallback編)
- React hooksを基礎から理解する (useMemo編)
- React hooksを基礎から理解する (useRef編) 今ここ
useRefとは
関数コンポーネントでは、Classコンポーネント時のref属性の代わりに、useRef
を使って要素への参照を行います。
またuseRef
では、useState
のようにコンポーネント内での値を保持することが出来ます。
構文
const refObject = useRef(initialValue)
//例
const number = useRef(100);
console.log(number.current); // 100
useRef
は、.current
プロパティが渡された引数(初期値はinitialValue)をrefObject
へ返します。
この引数の値が書き換え可能な.current
プロパティーの値であり、 .current
プロパティ内に保持することができます。
DOMを参照したい場合
const inputElement = useRef(null)
//例: inputElement.currentで <input type="text" /> を参照
<input ref={inputElement} type="text" />
console.log(inputElement.current); // <input type="text" />
DOMの参照例
useRef
でrefオブジェクトを作成したものをref属性(HTML要素)に指定してDOMを参照しています。
const App = () => {
const inputEl = useRef(null);
const handleClick = () => {
inputEl.current.focus();
console.log("inputEl.current:", inputEl.current);
//inputEl.current: <input type="text">
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={handleClick}>入力エリアをフォーカスする</button>
</>
);
};
ボタンクリックで<input type="text">
がfocusされました。
参照:React公式サイト
useRefとuseStateをくらべてみる
useRefを使ってDOMを参照
useRefを利用するとtext
のstate更新時にのみコンポーネントの再レンダリングが発生します。
const App = () => {
const inputEl = useRef(null);
const [text, setText] = useState("");
const handleClick = () => {
setText(inputEl.current.value);
};
console.log("レンダリング!!");
return (
<>
<input ref={inputEl} type="text" />
<button onClick={handleClick}>set text</button>
<p>テキスト : {text}</p>
</>
);
};
useStateを使ってDOMを参照
入力中の文字列をステートinputElement
に格納、ボタンが押された時にsetText(inputElement)
でtext
stateへ代入することでuseRef
を使った時と同じ挙動にしています。この場合、text
とinputElement
のstate更新時の両方でコンポーネントの再レンダリングが発生しています。
const App = () => {
const [inputElement, setInputElement] = useState("");
const [text, setText] = useState("");
const handleClick = () => {
setText(inputElement);
};
console.log("レンダリング!!");
return (
<>
<input
value={inputElement}
onChange={(e) => setInputElement(e.target.value)}
type="text"
/>
<button onClick={handleClick}>setText</button>
<p>テキスト : {text}</p>
</>
);
};
useState
を利用している場合はstateの変更される度にコンポーネントの再レンダリングが発生しますが、useRef
は値が変更になっても、コンポーネントの再レンダリングは発生しませんでした
コンポーネントの再レンダリングはしたくないけど、内部に保持している値だけを更新したい場合は、保持したい値をuseState
ではなく、useRef
を利用するのが良さそうです。