【React】コンポーネントとReact Hooksについて

React初学者用に頻出React Hooksを解説した記事になります。

はじめに

ギークフィードの松浦です。

この記事はギークフィードアドベントカレンダー2023の5日目の記事になります。

ギークフィードでは勉強会を毎週木曜日に社内勉強会を実施しています。

本記事は私が社内勉強会でReact勉強会を開催した際の資料をブログ公開用に改稿した記事となっています。

React Hooksについて解説した後最後に簡単な演習問題を一問載せてるので是非実装してみてください。

最新のフロントエンド技術の動向について

まずはじめに、Reactは現在、フロントエンド開発において非常に人気があり、広く使用されています。これは、Google TrendsやState of JavaScriptのデータが示す通りであり、Reactに対する需要が非常に高まっていることを示唆しています。

  • Google trends

上二つのグラフを見るとReactはフロントエンド技術においてかなり突出して使用されているトレンド技術だということがわかると思います。

そのためReactエンジニアを欲しているWeb系企業はかなり多く、Reactを覚えると市場で市場価値の高いエンジニアになれることは間違い無いでしょう。

 

Reactの特徴

ReactはMeta社が開発したWebアプリのUI構築に特化したJavaScriptライブラリです。

Meta社のInstagramなどもReactで開発されています。

Reactは以下のような特徴があります。

宣言的なView

React は、アプリケーションの各状態に対応するシンプルな View を設計するだけで、データの変更を検知し、関連するコンポーネントだけを効率的に更新、描画します。

コンポーネント指向

Reactでは、UIを再利用可能な部品(コンポーネント)に分割しそれらを組み合わせてWebアプリを構築します。これにより、コードの再利用性が高まり、保守性が向上します。

仮想DOM

仮想DOMは、Reactが内部的に使用している技術であり、DOMの変更を最小限に抑えることができます。Reactは、仮想DOM上で変更を行い、必要な部分だけを実際のDOMに反映させるため、パフォーマンスが向上します。

React開発環境構築について

ここからはReactでの開発手法を紹介していきます。

プログラミング言語の習得には実際に手を動かし、理解を深めることが重要です。

この記事をご覧になっていただいているみなさんも実際にローカルで動かしてみてください。

前提条件

Node.jsをローカルにインストールしていること

環境情報

私が今回使ってるバージョン(無理に合わせる必要はないです。)

Node.js 20.9.0 (10/30段階でLTS)

https://nodejs.org/en/

環境構築

まず、Nodejsがインストールできたらターミナルで以下のコマンドを打ちます。

今回はTypeScriptを使用します。

TypeScriptを使用しない場合は--template typescript
 を入れずにコマンドを打ってください。

これで準備ができました。

上のようなディレクトリが自動生成されていると思います。

またエディターで作ったフォルダを開き以下のコマンドを打ってみましょう。

するとブラウザが立ち上がり、上のようなページが開かれればOKです。

上のページの描画を定義しているコードは「src/App」にあります。

少し書き換えて反映されるか試してみてください。

関数コンポーネント

ReactにおいてUIを構成する部品のことをコンポーネントと呼びます。

このコンポーネントは関数コンポーネントとクラスコンポーネントの二種類ありますが、現在においては関数コンポーネントを使用することが推奨されています。

昔のReact公式ページはクラスコンポーネントで書かれていましたが、現在は全て関数コンポーネントで書かれています。

古:https://ja.legacy.reactjs.org/

新:https://react.dev/

その理由は

  • 関数コンポーネントの方がシンプルにコンポーネントを定義できる点
  • 後述するReact Hooksの導入によりstateやコンポーネントライフサイクルの実装が容易で柔軟性が高くなったため

となっています。

書き方はシンプルで以下のように定義してあげれば簡単にUIを定義できます。

今回はTypeScriptなのでtitleの型定義も行いました。

このコンポーネントを使うには、呼び出し元のコンポーネントで以下のようにコンポーネントのimportを行い、JSXタグで呼び出します。

Learn Reactの下にMyButtonコンポーネントを配置しました。すると、

このように定義したコンポーネントを使うことができます。

なお、Reactの型は他にも

などと定義することもできます。

下の場合はReact.FCを使用して関数コンポーネントの型を定義しています。React.FCは、Propsの型をジェネリクスとして受け取ります。この方法は、Propsに子要素(children)が含まれる場合、またはPropsにデフォルト値がある場合に特に役立ちます。

React Hooks

Reactライブラリでの関数コンポーネント内での状態管理やライフサイクルイベントの利用を可能にする新しい機能です。これは、クラスコンポーネントに依存する従来の方法に代わるものとして、React v16.8で導入されました。

React Hooksの主なメリットは以下の通りです:

  1. 関数コンポーネント内での状態管理: React Hooksは、useStateフックを介して簡単にコンポーネントの状態を管理するための手段を提供します。これにより、クラスコンポーネントと同様に状態を持つことができます。
  2. 副作用の管理: useEffectフックを使用すると、コンポーネントのレンダリングサイクルの間に発生する副作用(データの取得、サブスクリプションの設定など)を処理できます。
  3. カスタムフックの作成: 関数内でフックを使用して、カスタムフックを作成できます。これにより、コードの再利用が容易になります。

React Hooksはコンポーネントの記述を簡潔にし、複雑な状態やライフサイクル管理をより直感的かつ効果的に行うことができるようにしてくれます。

useState

useStateは、Reactで状態を保持するためのReact HooksでuseStateを使うことで、コンポーネント内で状態を管理することができます。

Reactではこのstate(状態)が変わったときに再レンダリングされます。

例えば以下のように定義します。

上記の例では、count は初期値0の数値型定数で、textは初期値が空文字列の文字列型定数であり、setCountcountの状態を、setTexttextの状態を更新するための関数です。useStateは、配列を返し、配列の1番目の要素には現在の状態の値が、2番目の要素には状態を更新するための関数が格納されます。例えば、以下のようにtextの値を更新することができます。

また、setStateにはコールバック関数を入れることができ、その引数は直前の値になります。

なので上のように定義した場合直前の値に1を足したものがcountにセットされます。

count++; などのようなインクリメントを使い直接countを更新するようなことはできないので注意しましょう。

以下のように定義すると+ボタンを押下するとincrement関数が処理され、countの値が1増え、ーボタンを押下するとdecrement関数が処理されるのでcountの値が1減ります。

+ボタンを押し続けると無限に増えていきます。

ここで注意していただきたいのが、set関数を呼び出しても、実行中のコードの状態は変わりません

以下のコードは、一見するとログにはセットされた新しいカウントが出力されそうですが、そうではありません。

これは、状態がスナップショットのように動作するためです。count状態を更新すると、新しい状態値を使用して別のレンダリングが要求されますが、すでに実行されているイベント ハンドラーの JavaScript 変数には影響しません。

処理の中で新しい値を使用したい場合は以下のように新しい値を変数に保存することで回避しましょう。

他にもuseRefを使用することでも最新の値を使用することができます。 気になる方は以下を参考に自学してみてください。 https://react.dev/reference/react/useRef

useEffect

useEffectは、React Hooksの一つで、コンポーネントのライフサイクルに関する処理を実行するために使用されます。例えば、コンポーネントがマウントされた時、アンマウントされた時、または更新された時に実行される処理を定義することができます。

以下は、useEffectの基本的な使い方です。

第1引数には、実行したい処理を記述します。第2引数には、依存する値の配列を渡します。この配列に含まれる値が変更された場合に、再度処理が実行されます。空の配列を渡すと、初回レンダリングのみ実行されます。

例えば、以下の例ではtextを依存配列としたuseEffecttextの値が変わる度に長さをtextLengthにセットする処理を行っています。

上の例くらいの操作であれば

としても同じなので後者の方が良いです。

また、外部システムと同期するためにuseEffect を使用することも多いです。

例)

このようにuseEffectを使うことでAPIからデータを取得し、そのデータを使うことができます。

useMemo useCallback

次に、Reactでは不要な再レンダリングを防ぐために値や関数をキャッシュすることができます。

以下のように書くことで再レンダリングのパフォーマンスを最適化することができます。

useMemoは第一引数にはキャッシュしたい値を計算する関数を設定します。この関数は純関数で、引数を取らず、任意の型の何らかの値を返す必要があります。第2引数には、依存する値の配列を渡します。この配列に含まれる値が変更された場合に、再度処理が実行されます。例えば空の配列を渡すと、初回レンダリングのみ処理が行われ、その他のレンダリングでは再計算されないためパフォーマンスが最適化されていると言えます。

useCallbackは、関数をメモ化するためのフックです。関数が再生成されることを防ぎ、パフォーマンスを向上させます。

処理に必要なStateは必ず依存配列に入れる必要があります。

今回の場合、依存配列のtextの値が更新された時のみ関数による再計算が行われます。

以下のコードのように依存配列にtextを入れ忘れてしまうと初回レンダリングのみtextLengthの計算処理が行われますのでどれだけテキストボックスに文字を入れてもtextLengthの値は0となります

カスタムフック

カスタムフックは、Reactのフックの一つで、カスタムフックを使用することで、コンポーネントからロジックを抽出し、再利用可能な関数を作成することができます。このようにすることで、UIと処理のコンポーネントを完全に分離することもできるようになります。

UIと処理を分離することで、コンポーネントの記述が簡潔になり、コンポーネントの複雑化を防ぐことができます。また、カスタムフックを使用することで、同じロジックを複数のコンポーネントで再利用することができます。これにより、コードの重複を避けることができ、保守性の高いコードを書くことができます。

以下は、カスタムフックの基本的な使い方です。

カスタムフックは必ずuse から始める必要があります。

こちらは先程のコードをロジックのみ切り分けたカスタムフックになります。

これをApp.tsxで読み込むには以下のように書くことができます。

このようにUIコンポーネントでは値や関数を受け取ることができます。

演習

ここまででReactの基礎を解説してきました。

ローカルで手を動かせる人は以下のような動きをするようにコーディングしてみてください。

Ex1)useStateを使い以下の処理を実装してください。

 

こちらのGithubページに解答例が載っているので参考にしてみてください。

おわりに

以上でReact入門を終わりたいと思います。

以下にこれらのコードが入ったGithubページを載せておきます。

GIthubページ

この記事が気に入ったら
いいね ! しよう

Twitter で

【採用情報】一緒に働く仲間を募集しています

採用情報
ページトップへ