Reactでプログラムを書いていく中で、以下のように思うことがありませんか??
- 何かしらの値が更新された際に特定の処理が並行的に行われるようにしたい
- とある処理をコンポーネントが生成された際に1度だけ呼び出すようにしたい
そんな時に役に立つReactのhooksを今回は、ご紹介します。
useEffectとは
以下、公式のページになっております。参考までに載せておきます。
記述方法
活用例
- 依存配列(第二引数)に設定した値が更新された際にのみ実行する処理をコールバック関数内に記述
- コンポーネントが生成されたタイミングで1度だけ呼び出す(再レンダリングの影響を受けない)
- 並行処理(非同期処理)の実装
- Reactにとって副作用(documentオブジェクトを使用したDOMの変更など関数外に影響を与える処理)となる処理の実行
簡単なカウントアップアプリを作成
ここまでの説明のみではイメージできない部分も多いかと思いますので、useEffectを使った簡単なカウントアップアプリを作成してみましょう。
- ①新規のReactの環境を構築
- ②Appコンポーネントの修正
まずは、src/App.jsを開き、以下のように修正しましょう。
const App = () => { return ( <></> ) } export default App
- ③useState, useEffect関数をインポートする
Appコンポーネントの上部に次のコードを記述してください。
import { useState, useEffect } from "react"
- ④useStateを定義
Appコンポーネント内に次のコードを記述してください。
// 1ずつカウントする値を保持 const [count, setCount] = useState(0) // countの値が変化するたびにuseEffect内で2ずつカウントされる値を保持 const [state, setState] = useState(count)
- ⑤JSXを記述
普通にカウントした値とuseEffect内でカウントしていく値をそれぞれ表示するようにしています。また、ボタンがクリックされた際には、handleClick関数を呼び出します。
※ 設定しているclassについては、後ほど確認することとします。
return ( <> <div className="wrap"> <div className="count"> <p>{`カウント : ${count}`}</p> <button onClick={handleClick}>クリック</button> </div> <div className="effect"> <p>{`useEffect内の処理 : ${state}`}</p> </div> </div> </> )
⑥handleClick関数を定義handleClick関数内では、setCount関数を呼び出し、countの値を+1する処理を記述します。// ボタンがクリックされた際に呼び出す const handleClick = () => { setCount((n) => n + 1) }
⑦useEffect関数を定義・処理を記述こちらは、useStateの下に記述していきます。// ボタンがクリックされ、stateの値が更新されるたびに動作する useEffect(()=>{ // countの値が0の時は動作しないようにする if(count!==0){ setState((c)=>c+2) } }, [count])
第二引数には、countを設定していますので、countの値が変更されない限りは、useEffect内の処理は再レンダリング(再描画)の影響を受けません。⑧App.cssを変更App.css内の記述はすべて削除し、以下のものに書き換えます。※ App.jsの上部でimportするのを忘れないようにしましょう。body { margin: 0;padding: 0; } .wrap { display: flex; flex-direction: column; align-items: center; padding: 2em 0; background-color: rgb(249, 255, 224); } .count p, .effect p, button { font-size: 20px; } button { border-radius: 10px; background-color: aliceblue; border: 2px dotted blue; cursor: pointer; box-shadow: 0px 5px 5px 0px rgb(201, 201, 254); } button:active { margin-top: 0.05em; box-shadow: 0px 2px 2px 0px rgb(201, 201, 254); }
⑨動作確認DEMOと同じように、動作をしていればOKです。以下の手順で動作の確認をしてみてください。- ボタンをクリック
- カウントの数値が+1される
- カウントの数値が変わるたびにuseEffect内の処理(+2する)が動いているか
動作的には、カウントが+1するのに並行して、useEffect内の処理が+2されるような感じです。実際に書いてみるとイメージしやすいですね!依存配列を空にすると、初回にしか呼ばれない
余裕のある方は、useEffectに関する記述を以下のように修正したうえで、再度、動作確認をしてみてください。useEffect(() => { setState((c) => c + 2); console.log("useEffectが呼ばれた"); }, []);
いくらボタンをクリックしてもuseEffect内の値は4以上にはなりません。つまり、第二引数を設定しない場合は、初回にしか呼ばれることはありません。
では、なぜ4という数値は表示されているのかと疑問に持った方もいたかもしれませんが、Reactでは潜在的な問題を探ることを目的に、ルートのコンポーネントを<StrictMode></StrictMode>で囲ってますので、本来1回しか呼ばれないものでも2回呼び出されるようになっています。
<StrictMode></StrictMode>をコメントにするだけで、1回しかuseEffectが呼ばれないようにすることも可能です。(index.jsで確認が出来ますが、小さな問題でもできるだけ解消していくのがベストですので、開発上はそのままにしておくのが、オススメです。)
まとめ
useEffectの活用例
- 依存配列(第二引数)に設定した値が更新された際にのみ実行する処理をコールバック関数内に記述
- コンポーネントが生成されたタイミングで1度だけ呼び出す(再レンダリングの影響を受けない)
- 並行処理(非同期処理)の実装
- Reactにとって副作用(documentオブジェクトを使用したDOMの変更など関数外に影響を与える処理)となる処理の実行
他のhooksについてもご紹介してます!
【React hooks】useState・propsの基礎を習得 - カウンターアプリ本記事内では、React hooksで提供される関数の一つである「useState」と「props」の基礎的な使い方をカウンターアプリを作成しながら解説していきます。React初心者の方やStateやpropsの処理の流れに不安がある方向けに書いております。【React hooks】useReducerの基礎を習得 - カウンターアプリ本記事では、React hooksで提供されている関数であるuseReducerの使い方やuseStateの主な違いなどを解説しております。実際にuseStateを用いて作成したカウンターアプリをuseReducerで書き換えますので、処理の流れや具体的なコードの書き方を理解するきっかけになればと思います。【React hooks】useContextの基礎を習得 - カウンターアプリuseContextを使うことで異なる階層であってもデータの共有が出来るようになるため、コンポーネント間で同じデータ(State)を共有したい場合や機能や用途に応じてデータの管理をしたい時にとても便利です。また、propsの受け渡しも最小限に抑えることが出来る点に加え、useReducerとあわせて使用されることが多い関数になります。[ React hooks ] useRefの使い方・サンプルコード (useStateとの違いも解説!)本記事では、React hooksの一つである「useRef」についての使い方からuseState・useReducerとの違いまで解説しております。また、「カウンター機能」と「ref属性の活用」の2本立てでサンプルコードを掲載しておりますので、学習の参考にしてもらえたらと思います。
コメント