
React Hooks登場でコンポーネントはどう変わった?
2021.12.20
React Hooks とは?
「React Hooks」とは、React16.8より追加された新機能です。
これにより、クラスコンポーネントでしか使えなかった機能が、関数コンポーネントでも使えるようになりました。
【React 公式ドキュメント - フックの導入】
https://ja.reactjs.org/docs/hooks-intro.html
今回は、ReactHooks 登場前後のコンポーネントを比較し、「記法がどのように変わったのか」を見ていきたいと思います!
実装するサンプル
違いを分かりやすくするために、以下のような機能を持ったコンポーネントを実装します。
- 状態として count という変数を持つ
- カウントアップボタンを押すことで、 count をインクリメントする
- count は常に画面上に表示する
- コンポーネントのマウント時・状態の更新時・アンマウント時に、それぞれコンソール出力する
それではさっそく、実装サンプルを見ていきましょう!
クラスコンポーネントで実装した場合
まずは、従来通り「クラスコンポーネント」で実装した場合です。
従来の React の記法に慣れた方にとっては、少し冗長な表記になるかもしれません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import React from "react"; class NormalComponent extends React.Component { /** * コンストラクタ */ constructor() { super(); /** * 画面の状態を初期化 */ this.state = { count: 0, }; } /** * コンポーネントマウント後処理 */ componentDidMount = () => { console.log("[NormalComponent] componentDidMount"); }; /** * コンポーネント更新時処理 */ componentDidUpdate = () => { console.log("[NormalComponent] componentDidUpdate"); }; /** * コンポーネントアンマウント前処理 */ componentWillUnmount = () => { console.log("[NormalComponent] componentWillUnmount"); }; render = () => { const { count } = this.state; return ( <> <p>{`This Component is NormalComponent (${count.toString()})`}</p> <button onClick={() => { // ボタンを押下したタイミングでthis.setStateを使いstateを加算する this.setState({ count: count + 1 }); }} > Count Up </button> </> ); }; } export default NormalComponent; |
ここがポイント!
コンストラクタでコンポーネントの状態である state を初期化し、ボタン押下のタイミングで setState を用いて更新します。
また、コンポーネントがマウント・アンマウントされたタイミングや、状態が更新されたタイミングはそれぞれ componentDidMount , componentWillUnmount , componentDidUpdate といった React のライフサイクルメソッドを用いて検知し、コンソールに出力しています。
React Hooks を使った関数コンポーネントで実装した場合
続いて、「React Hooks」を使った実装パターンを見てみましょう。
React Hooks を使う際のルールとして、「関数コンポーネント中のトップレベル」で定義する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import React, { useEffect, useState } from "react"; const HooksComponent = () => { // マウントされたかどうかをisMountedで管理 const [isMounted, setIsMounted] = useState(false); const [count, setCount] = useState(0); // 第二引数に空の配列を設定することでマウント・アンマウント時のみ起動する useEffect(() => { // returnで関数を返却することで、 // useEffectの状態監視が終了した(=アンマウントされた)タイミングで起動する return () => { console.log("[HooksComponent] useEffect willUnmount"); }; }, []); // 第二引数にcountを含めた配列を設定することで、countの変更を監視する useEffect(() => { // isMountedの状態によりクラスコンポーネントでの // componentDidMountとcomponentDidUpdateを判別する if (isMounted) { console.log("[HooksComponent] useEffect disUpdate"); } else { console.log("[HooksComponent] useEffect didMount"); setIsMounted(true); } }, [count]); return ( <> <p>{`This Component is HooksComponent (${count.toString()})`}</p> <button onClick={() => { // ボタンを押下したタイミングでsetCountを使いcountを加算する setCount(count + 1); }} > Count Up </button> </> ); }; export default HooksComponent; |
クラスコンポーネントでの実装に比べると、全体的に記述量が減っているのが一目瞭然ですね。
ここがポイント!
useState
React Hooks では、 useState で state を定義しています。
this.state や this.setState なしで state が扱えます。
useEffect
useEffect で、関数コンポーネントでライフサイクルメソッド機能が使用可能になります。
クラスコンポーネントで使用した、以下の3つがまとまったものとイメージすれば分かりやすいでしょう。
- componentDidMount
- componentWillUnmount
- componentDidUpdate
isMounted
また、 count に加えて isMounted という真偽値型の状態を持たせています。
関数コンポーネントでは、コンポーネントがマウント済みかどうかの状態を独自で持つ必要があるためです。
動作検証用コンポーネント
実際に、お手元の環境で上記コンポーネントの動作検証をする場合、以下をお使いください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import React from "react"; import NormalComponent from "./NormalComponent"; import HooksComponent from "./HooksComponent"; export default class ComponentManager extends React.Component { constructor() { super(); this.state = { showComponent: true, }; } render = () => { const { showComponent } = this.state; return ( <div> <button onClick={() => this.setState({ showComponent: !showComponent })} > {`Show/Hide Component`} </button> {showComponent ? ( <div> <NormalComponent /> <HooksComponent /> </div> ) : null} </div> ); }; } |
showComponent という状態を持ち、その値によって NormalComponent と HooksComponent の2種のコンポーネントのマウント・アンマウントを制御しています。
「Show/Hide Component」のボタンをクリックすると、各コンポーネントのマウント・アンマウント処理が正常に行われていることを確認できます。
さいごに
今回は、「React Hooks 登場前後のコンポーネントの違い」について解説しました。
クラスコンポーネントと React Hooks を用いた関数コンポーネントとでは、同じ挙動をさせる場合でも記法が大きく異なることが分かりますね。
両者とも基本の記法を覚えておけば、2つを組み合わせて複雑な処理を実現することが可能です。
ぜひ、しっかり覚えておきましょう!
こちらの記事もオススメ!
書いた人はこんな人

- 「好きを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もり大歓迎!
また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。
以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit
ライトコードの日常12月 1, 2023ライトコードクエスト〜東京オフィス歴史編〜
ITエンタメ10月 13, 2023Netflixの成功はレコメンドエンジン?
ライトコードの日常8月 30, 2023退職者の最終出社日に密着してみた!
ITエンタメ8月 3, 2023世界初の量産型ポータブルコンピュータを開発したのに倒産!?アダム・オズボーン