そうお困りではありませんか?
ReactではHooksという便利な機能を使って開発することができます。
本記事では、よく使う8種類のHooksについて用途、使い方をわかりやすくまとめていきます。
「useEffect」
「useContext」
「useRef」
「useReducer」
「useMemo」
「useCallback」
「Custom Hooks」
Reactをこれから学ぼうと思っている方向けの入門編です、ぜひ参考にしてみてください。
・具体的な使い方
useState
useState(ユーズステート)はその言葉の通り、「State」=「状態」の意味。
ここでの状態が何なのかというと「データの状態」を指しています。
「useStateはデータの状態が変化したらレンダリングする」仕組みなので、
たとえば、ボタンをクリックしたら数字をカウントアップするような動作をWebページを更新することなく、画面の表示を変化させることが出来ます。
用途:変化するデータの状態を管理したい時、propsなどで再利用したい時に指定します。
使い方:
const [変数名,set変数名] = useState(初期値);
で指定出来ます。
変数名は任意の名前でいいですがカンマ区切り後の値は同じ変数名にして「set○○○○」となるように指定します。
例:
const [count,setCount] = useState(0);
そしてreactからのインポートも忘れず指定しましょう。
import { useState } from "react";
const [count,setCount] = useState(0);
useEffect
useEffect(ユーズエフェクト)は処理のタイミングを指定することが出来ます。
書き方:
useEffect( (引数) => {
実行したい処理
} , [処理したいタイミング]);
第一引数には処理したい内容を指定、第二引数の配列の中には処理をしたいタイミングを指定します。
ちなみに配列の中を空にすればマウントされたタイミングで実行されます。
useContext
useContext(ユーズコンテキスト)は、たくさんのコンポーネントで開発されたアプリなどで活躍します。
propsなどで子コンポーネントへデータを渡す場合、コンポーネントの数が多ければ多いほど煩雑になりバケツリレー形式になってしまいます。
その結果、「このデータはどこのデータから持ってきているのか?」というムダ確認の工数を生んでしまいますが、useContextはグローバルなデータを管理することで、どこからでもpropsとしてデータを読み込むことが出来ます。
const MyContext = React.createContext();
function Parent() {
return (
<MyContext.Provider value="Hello World">
<Child />
</MyContext.Provider>
);
}
function Child() {
const value = useContext(MyContext);
return <h1>{value}</h1>;
}
上記の例では、MyContextを作成しParentコンポーネントでProviderを作成しvalueプロパティを渡しています。
Childコンポーネントでは、useContextフックを使用してContextを使用してvalueを読み取り<h1>タグに表示しています。
このように、useContextを使用することでReactのコンポーネントツリー内でのデータの受け渡しを簡単にすることができます。
useRef
useRef(ユーズレフ)のレフは「reference」の略で参照するの意味があります。
useRefはDOM要素やコンポーネントのインスタンスを参照するためのフックで、指定したHTMLタグの中身を参照することが出来ます。
const 定数名 = useRef();
以下の例では、nput要素を参照するためにinputRefという名前の参照オブジェクトを作成しています。
そして、inputRefをinput要素のrefプロパティに設定しています。
これによりinput要素に対する参照を取得できます。
const inputRef = useRef(null);
return (
<form onSubmit={handleSubmit}>
<label> Name:
<input type="text" ref={inputRef} />
</label>
<button type="submit">Submit</button>
</form>
);
useReducer
useReducer(ユーズレデューサー)はReactのHooksの一つで、状態管理のための関数です。
useStateと同様に状態を管理することができますが、より複雑な状態管理が必要な場合に使用されます。
useReducerは2つの引数を取ります。
1つ目は現在の状態を表すstate変数と2つ目はstateを更新するためのdispatch関数です。
dispatch関数は現在の状態と新しい値を引数に取り新しい状態を返します。
以下は、useReducerを使用した例です。
import React, { useReducer } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</>
);
}
上記の例では、initialStateとreducer関数を定義しuseReducerを使用して初期状態を設定しています。
Counterコンポーネントではstate変数とdispatch関数を取得し、
ボタンがクリックされるたびにdispatch関数を使用してstateを更新しています。
useMemo
useMemo(ユーズメモ)は、計算に時間がかかる処理の結果をキャッシュし、
同じ処理を繰り返さないようにするためのReactのHookです。
例えば、非常に大量のデータを処理する場合や、複雑な演算を行う場合に使われます。
useMemoの基本構文は次のとおりです。
const 定数名 = useMemo(() => 関数名(), [配列]);
useMemoは、2つの引数を取ります。
1つ目は計算結果を返す関数であり、2つ目はその関数が依存する値の配列です。
依存する値の配列は常に必要なものを指定するようにしましょう。
このようにすることで依存する値が変更された場合にだけ再計算されます。
import { useMemo, useState } from 'react';
function calculateSum(a, b) {
console.log('calculateSum function was called!');
return a + b;
}
function App() {
const [num1, setNum1] = useState(0);
const [num2, setNum2] = useState(0);
const sum = useMemo(() => calculateSum(num1, num2), [num1, num2]);
return (
<div>
<input type="number" value={num1} onChange={(e) => setNum1(+e.target.value)} />
<input type="number" value={num2} onChange={(e) => setNum2(+e.target.value)} />
<p>The sum is: {sum}</p>
</div>
);
}
上記の例では、2つの数値を入力しその和を表示するコンポーネントを作成しています。
calculateSum関数は2つの数値の和を計算する関数です。
この関数が時間がかかる処理だと仮定しuseMemoを使ってその結果をキャッシュします。
sumは、num1とnum2が変更された場合にのみ再計算されるように指定されています。
注意点としてuseMemoを使いすぎるとメモリ使用量が増加してしまう場合があるので、
必要な場合にのみ使用するようにしましょう。
また、パフォーマンスの問題を抱えている場合はuseCallbackを検討することも重要です。
useCallback
useCallback(ユーズコールバック)は、関数をメモ化して再レンダリング時に再生成されないようにするReactフックです。
コンポーネントが再レンダリングされると、そのコンポーネント内で定義された関数も再生成されますが、
useCallbackを使用すると関数が再生成されるのを防ぐことができます。
具体的には、useCallbackは第一引数に渡された関数をメモ化して、
第二引数に渡された値が変更された場合にのみ新しい関数を生成します。
このようにすることで、関数が不必要に再生成されることを防ぎパフォーマンスを向上させることができます。
たとえば、以下のようなコンポーネントがあったとします。
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
};
このコンポーネントではincrement関数が毎回再生成されます。
しかし、increment関数はcountステートを更新するためだけに使用されているため再生成する必要がありません。
そこで、increment関数をuseCallbackでメモ化することで不必要な再レンダリングを避けることができます。
import React, { useState, useCallback } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
};
ここで、increment関数はuseCallbackでメモ化されており第二引数にcountを渡しています。
これにより、countが変更された場合にのみ新しい関数が生成されます。
Custom Hooks
Custom Hooks(カスタムフック)は、Reactのフック(Hooks)を用いて機能を分割したもので、再利用可能なコードのまとまりです。
Custom Hooksを使うことで同じ機能を複数のコンポーネントで使いまわすことができコードの重複を避けることができます。
import React, { useState } from 'react';
function useCounter(initialValue, step) {
const [count, setCount] = useState(initialValue);
const increment = () => {
setCount(count + step);
};
const decrement = () => {
setCount(count - step);
};
return [count, increment, decrement];
}
function Counter() {
const [count, increment, decrement] = useCounter(0, 1);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default Counter;
上記の例では、useCounterというカスタムフックを作成して、
useStateフックを使用してカウンターの値を管理しています。
useCounterフックは、初期値とステップ値を引数として受け取りカウンターの値とインクリメント・デクリメントの関数を返します。
Counterコンポーネントでは、useCounterフックを使用してカウンターの状態を管理し、
それを表示するためのUIをレンダリングしています。
Counterコンポーネントは、incrementとdecrementの関数をボタンのonClickハンドラーに渡しています。
最後に
Reactのよく使うHooks、8種類を解説しました。
Hooksはほかにも「useImperativeHandle」「useLayoutEffect」「useDebugValue」がありますが、
個人的にあまり使わないかな?と思うので省略しました。
もし気になる方は上記のキーワードで検索して詳しく調べてみてください。
最後までお読みいただきありがとうございました。