[初心者向け]Reactの基礎を徹底解説してみた

#はじめに
今回はReactの使い方についてまとめていきます。

環境構築については、以下の記事を参考にしてください。

[WindowsでReactの環境構築をしてみる](https://qiita.com/renesisu727/items/4b34df1a3cfe8d534303)

#コンポーネントについて
Reactはコンポーネント(部品)という単位で実装していきます。

Webサイトやアプリは、ボタンやタブなどのコンポーネントの集まりと考えることができます。

例えば、このQiitaだと以下のようなコンポーネントが存在すると考えることができます(適当です)。

+ ボタンコンポーネント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/9e14af05-994a-e0d7-07f3-f4afd745198f.png)

+ ナビゲーションコンポーネント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/e01bcce4-c4ad-d1a0-b8c8-0d7898978522.png)

つまり、コンポーネントとは`見た目`と`機能`を組み合わせたものだと考えることができます。

このように、コンポーネントという単位でプログラムを管理すると、再利用することができたり、変更してもバグが起きにくいという利点がありますよね。

それでは実際にコンポーネントの種類を見ていきましょう。

今回は、`npx create-react-app`というコマンドを使ってReactアプリを作成し、そのアプリに各々のコードを記述して動きを見ていきます。


##Functional コンポーネントについて
Functionalコンポーネントについて見ていきましょう。

`create-react-app`を行うと、以下のようなファイル構成になります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/fd5a2e86-0ee1-0850-7b49-1f2224a43fde.png)


この中の`App.jsx`に以下のようにコードを記述してください。


```App.jsx
import React from 'react'

const App = (props) => {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  )
}
export default App
```

このように、Javascriptの関数のようにReactのコンポーネントを作成して、外部にエクスポートしています。

Functionalコンポーネントは、アロー関数またはfunction()で定義した関数のどちらを用いて記述します。

関数内の`return`の後に、`JSX`と呼ばれるHTMLのようなものを記述します。

ここでは使用していませんが、引数で渡しているpropsに、親コンポーネントから呼び出す際に変数を格納されることができます。

ちなみに、このエクスポートされたApp関数は`index.js`で呼び出されます。

```index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

serviceWorker.unregister();
```

上記のように、`index.js`は`App.jsx`ファイルからエクスポートされた`Appコンポーネント`を読み込み、それを`ReactDOM`に渡すことでrender(描画)しています。

`yarn start`を行い、実行結果を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/2c090068-8c51-0f2c-10aa-e3ec9a38b8b8.png)

このように、Reactアプリを起動させると`index.js`ファイルが実行され、ReactDOMがrender(描画)されていることが分かります。

##クラスコンポーネントについて
クラスコンポーネントは以下のように作成します。

```App.jsx
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      open: 'pocomaru'
    }
  }
  render() {
    return (
      <div>
        <h1>Hello World</h1>
        <h1>{this.state.id}</h1>
      </div>
    );
  }
}
export default App
```

Javascriptのクラスを作成する際に、`React.Component`というクラスを継承しています。

その後に、`constructor`により、初期値の`state`をセットします。コンストラクタとは、オブジェクト作成時に実行されるメソッドのことでしたね。

引数に渡している`props`は、エクスポートしたAppコンポーネントを呼び出すときに渡した値が代入される箱のようなものです。

`super(props)`とすることで、親クラスを継承しています。

その後に、`this.state`にオブジェクトを代入します。このthisは、このクラス自身のことです。今、Appクラスのopen stateがtrueに設定されています。

このstateに設定されている値を用いる場合、`this.state.id`とすればアクセスできます。

return以降はJSXと呼ばれる部分になります。この部分では、通常の書き方ではJavascriptコードを使用することができません。

そのため、`this.state.id`の値にアクセスするためには、中括弧{}で囲う必要があります。

この状態でReactアプリを起動すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/92c2937d-5a49-a983-2ddb-417a01f164b6.png)


#Functionalコンポーネントとクラスコンポーネントの違い
最初にFunctionalコンポーネントの特徴から解説します。以下の特徴を持ちます。

* stateを持たない
* propsを引数に持つ

順番に解説します。


###stateとは
stateとは、その名の通り状態のことです。

例えば、扉コンポーネントというものを考えたとき、扉が`開いているのか`や`閉じているのか`というコンポーネントの状態を示すのがstateです。

ボタンコンポーネントでは、`押されたことがある`のか`押されたことがないのか`というのもstateで管理できますし、`何回押されたのか`などもstateで管理できます。

Functionalコンポーネントはクラスコンポーネントと違って、このstateを持つことができません。

React-hooksなどを用いればstateを持たせることは可能ですが、ここでは割愛させて頂きます。

###propsを引数に持つとは
Functionalコンポーネントは、propsを引数に持つことができます。ちなみにクラスコンポーネントもコンストラクタにpropsを渡すので、Functionalコンポーネントだけの機能ではありませんが。

propsとは、親コンポーネントから渡す値を格納する`箱`のようなものです。

具体例で確認してみましょう。

`App.jsx`という親コンポーネントから`Name.jsx`というコンポーネントを呼び出し、propsとしてnameを渡すことを考えてみましょう。以下のようになります。

```App.jsx
import React from 'react';
import Name from './Name';

const App = (props) => {
  return(
    <div>
      <Name name='pocomaru'/>
    </div>
  )
}
export default App
```

このファイルでは、`Name.jsx`の中の`Name`関数コンポーネントをインポートしています。

そのインポートした関数のname属性に`pocomaru`という値を渡しています。

この渡した値には、`props.name`とすることでアクセスできます。Name.jsxの中身を確認してみましょう。


```Name.jsx
import React from 'react';

const Name = (props) => {
    return (
        <h1>{props.name}</h1>
    )
}

export default Name
```

結果は以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/763eed32-ca0d-54ad-d78d-d81043dc8b8b.png)

それでは次にクラスコンポーネントについて見ていきましょう。

以下の特徴があります。

+ ライフサイクルをもつ
+ stateを持つ

それぞれについて解説していきます。

###ライフサイクルをもつ
クラスコンポーネントはライフサイクルを持ちます。

ライフサイクルとは、コンポーネントが生まれて、成長し、死ぬまでの循環のことです。

こんなことを言われても意味がわからないと思うので、具体的に説明します。

ボタンコンポーネントのライフサイクルについて考えてみましょう。

ある日、ボタンコンポーネントが誕生しました。マウントされるとも言いますね。

Reactにおいては、この`ボタンコンポーネントが誕生した瞬間`に`constructor`が走ります。stateに値を代入する処理などですね。

そのようにしてconstructorが走った後は、renderが走ります。これによりReactが描画され、画面で見ることができます。

この後に、`componentDidMount`という関数が走ります。このcomponentDidMount`に何か操作をかいておけば、コンポーネントがマウントされた後に一度だけ使うことができます。


ここまでが生まれたときの話です。次は、コンポーネントが成長していくときの話をしましょう。

コンポーネントが誕生した後は、度重なるrenderがユーザーの操作により発生します。

具体的にはrenderは、ユーザーの操作などによりstateが変更されるたびに呼び出されます。

これがライフサイクルの成長の過程であり、renderされる毎に`componentDitUpdate`という関数が実行されます。

最後に、コンポーネントが死ぬときの話をしましょう。

コンポーネントが死ぬ直前、つまりはアンマウントされる直前に`componentWillUnmount`という関数が実行されます。

このように、ライフサイクルに合わせて`componentDidMount`などのメソッドを実行することができ、これらはクラスコンポーネントでしか使用することができません。React-hooksを使えば、Functionalコンポーネントでも用いることができますが。

それでは次に、ライフサイクルについて解説していきます。

#ライフサイクルの種類
ライフサイクルには、以下の三種類があります。


* Mounting

* Updating

* UnMounting

各々について解説していきましょう

###Mountingとは
Mountingとは、コンポーネントが生まれるときの期間のことです。

このMountingのときに使われるライフサイクルメソッドは、マウントが行われる直前に実行される`componentWillMount`とマウントが実装された直後に実行される`componentDidMount`です。

ちなみにマウントが行われる直前に実行される`componentWillMount`は非推奨なので使わないほうがよいです。

##Updatingとは
Updatingとは、コンポーネントが変更される期間のことです。

クラスコンポーネントはライフサイクルとstateを持つことができます。

つまり、コンポーネントが変更されるとはこのstateが変更されることを指します。

例えば、ボタンコンポーネントを実装するとします。このボタンコンポーネントの元々の色は赤色で、ボタンをクリックすると青色になるという機能をもたせたいとします。

どのように実装するかというと、このボタンコンポーネントにstateを持たせて管理することが考えられます(例えばcolorコンポーネントを持たせてクリックにより変更させるなど)。

Reactにおける重要な点の一つは、このstateが変更されたときにrenderが走るということです。つまり、stateが変更されるたびに画面の一部分を再描画していきます。

なぜこのような事になっているのかというと、stateの変更を画面に反映させるためです。例えば先ほどの例でボタンコンポーネントをクリックして、colorというstateを赤色から青色に変更させたとします。しかし、例えstateが変更されたとしても、render(描画)されなければ画面に反映されません。そのため、Reactではstateが変更されるたびにrenderが呼ばれるようになっています。

この`stateが変更されてrenderされる`という時がUpdatingの期間であり、その前後に対応したライフサイクルメソッドが走ります。Updatingにおけるライフサイクルメソッドは、以下の4つが考えられます。

+ componentWillReactiveProps 　マウントされたコンポーネントが新しいpropsを受け取る前


+ shouldComponentUpdate 　　　新しいpropsやstateを受け取った時


+ componentWillUpdate　　　　　新しいpropsやstateを受け取った後、レンダリングする直前


+ componentDidUpdate　　　　　　更新が行われた直後


##Unmountingとは
コンポーネントが破棄される期間のことをUnMountingの期間といいます。

`componentWillUnmount`というライフサイクルメソッドが、コンポーネントが破棄される直前に呼び出されます。

それでは実際に、これらのライフサイクルメソッドを実装してみましょう。


#componentDidmountの実装
componentDidmountは、次の用途で用いられます。

+ Ajaxを使ったデータフェッチを行う(初回)
+ DOMに対する処理を行う(初回)
+ タイマーをリセットする
+ イベントリスナのセット

今回は、イベントリスナのセットを行っていきましょう。

LikeButtonコンポーネントを作成して、クリックするといいね数が増えていくという機能を実装します。

以下のように、App.jsxとLikeButton.jsxを実装しましょう。

```App.jsx
import React from 'react';
import LikeButton from './LikeButton';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }

  componentDidMount() {
    document.getElementById("counter").addEventListener('click', () => this.setState({count: this.state.count + 1}))
  }
  render() {
    return (
      <div>
        <LikeButton count={this.state.count} />
      </div >
    )
  }
}
export default App
```

```LikeButton.jsx
import React from 'react';

const LikeButton = (props) => {
    return (
        <div>
            <button id="counter">いいね数: {props.count}</button>
        </div>
    )
}
export default LikeButton
```

結果は以下のようになります。

![temp1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/f5410454-d9ad-a900-a9d9-b77e1fa79cf6.gif)


それではコードの解説をしていきます。

```.jsx
constructor(props) {
  super(props);
  this.state = {
    count: 0
  }
```

この部分で、Appコンポーネントのstateとしてcountを持たせています。

このstateをLikeButtonコンポーネントに渡して、その中のButtonをクリックするたびに、このstateが更新されていけば良いわけですね。

今回は、`componentDidMount`を用いてイベントリスナーを設定しています。イベントリスナーとは、イベント(文字入力やボタンクリックなど)が行われたことを検知して発動する関数のことです。これにより、コンポーネントが誕生したときにイベントリスナーをコンポーネントに設定することができます。

今回は、クリックというイベントが発生したときに、`() => this.setState({count: this.state.count + 1}`という関数が実行されるようになりました。

クラスコンポーネントのstateを変更するときは、このように`setStateメソッド`を用いて、そのメソッド内で関数またはオブジェクトを指定することにより、stateを変更することができます。クラスコンポーネント内でstateにアクセスするときには`this.state.***`としてアクセスします。ちなみに、このsetStateメソッド内で関数を渡すかオブジェクトを渡すかの違いによって、挙動が異なります。詳しくは以下の記事を参考にしてください。

[React の setState() の引数が関数の場合とオブジェクトの場合の違いについて整理する](https://qiita.com/im36-123/items/857c96ff60024c0d8a1c)

また、以下のコードでLikeButtonコンポーネントを呼び出し、propsとして`this.state.count`を渡しています。

```.jsx
<LikeButton count={this.state.count} />
```

このようにして渡したstateを、LikeButtonコンポーネントでは`props.count`という形で利用しています。


```.jsx
<button id="counter">いいね数: {props.count}</button>
```

このbuttonタグのidに`counter`を指定しています。このタグは、親コンポーネントであるApp.jsxからも指定して呼び出すことができます。

ここまでで、componentDidMountを用いてコンポーネントが誕生した直後にイベントリスナーを設定することができました。

###補足　別の方法で同じ機能を実装
また、今回の機能はApp.jsxからpropsとしてcountを更新する関数を渡し、それを子供のコンポーネントのボタンタグの`onClick`に指定することでも実装できます。

```App.jsx
import React from 'react';
import LikeButton from './LikeButton';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }

  UpdateCounter = () => {
    this.setState({
      count: this.state.count + 1
    })
  }
  render() {
    return (
      <div>
        <LikeButton count={this.state.count} UpdateCounter={this.UpdateCounter} />
      </div >
    )
  }
}
export default App
```

```LikeButton.jsx
import React from 'react';

const LikeButton = (props) => {
    return (
        <div>
            <button onClick={props.UpdateCounter}>いいね数: {props.count}</button>
        </div>
    )
}

export default LikeButton
```


#componentDidUpdateの実装
それでは次にstateが更新されてrenderが走った後に呼び出されるcomponentDidUpdateを実装していきましょう。

このライフサイクルメソッドは、`stateがある閾値を超えたときに別の動作をするようにしたい`ときなどに実装すると便利ですね。

今回は、いいね数が5という閾値を超えた際に、いいね数を0にするという機能を実装していきます。

componentDidUpdateはstateが更新され、それによりrenderが走った後に呼び出されます

つまり、その`更新されたstate`に対して更新されるたびにif文やswich文で比較を行い、指定した値になったときに指定した関数を実行する、といった処理を実装していきます

今回は`this.state.count`の値をcomponentDidUpdateの中で5と比較し、5以上になったときに`this.state.count`の値を`setState`メソッドを用いて0にするという機能を実装していきます。

以下のコードです。

```App.jsx
import React from 'react';
import LikeButton from './LikeButton';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }

  componentDidMount() {
    document.getElementById("counter").addEventListener('click', () => this.setState({count: this.state.count + 1}))
  }

  componentDidUpdate(){
    if (this.state.count >= 5) {
      this.setState({
        count: 0
      })
    }
  }
  render() {
    return (
      <div>
        <LikeButton count={this.state.count} />
      </div >
    )
  }
}
export default App
```

```LikeButton.jsx
import React from 'react';

const LikeButton = (props) => {
    return (
        <div>
            <button id="counter">いいね数: {props.count}</button>
        </div>
    )
}
export default LikeButton
```

以前の状態から追記したコードは以下だけです。


```.jsx
  componentDidUpdate(){
    if (this.state.count >= 5) {
      this.setState({
        count: 0
      })
    }
  }
```

このコードにより、stateの値が更新されるたびに`this.state.count`が5以上かどうかを確認することになります。

実行結果は以下のようになります。

![temp2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/e1f55ea1-709e-bd4b-2afe-4083c19a56e2.gif)

#componentWillUnmountの実装
このメソッドは主に次の機能を実装したいときに使います。

+ タイマーを解除する
+ イベントリスナーを解除する
+ 非同期処理を中止する

今回は、イベントリスナーを解除してメモリを開放する機能を実装していきましょう。

以下のコードです。

```App.jsx
import React from 'react';
import LikeButton from './LikeButton';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }

  componentDidMount() {
    document.getElementById("counter").addEventListener('click', () => this.setState({count: this.state.count + 1}))
  }

  componentDidUpdate(){
    if (this.state.count >= 5) {
      this.setState({
        count: 0
      })
    }
  }

  componentWillUnmount() {
    document.getElementById('counter').removeEventListener('click', () => this.setState({count: this.state.count + 1}))
  }
  render() {
    return (
      <div>
        <LikeButton count={this.state.count} />
      </div >
    )
  }
}
export default App
```


```LikeButton.jsx
import React from 'react';

const LikeButton = (props) => {
    return (
        <div>
            <button id="counter">いいね数: {props.count}</button>
        </div>
    )
}
export default LikeButton
```

これでコンポーネントがアンマウントされたときにイベントリスナーを削除して、メモリを開放することができるようになりました。

追記したのは以下の部分です。

```.jsx
  componentWillUnmount() {
    document.getElementById('counter').removeEventListener('click', () => this.setState({count: this.state.count + 1}))
  }
```

このコードにより、イベントリスナーを削除することができています。

それでは次に、ReactのHooksについてまとめていきます。

#Hookとは
Hookとは、端的に言えばクラスコンポーネントの機能をFunctionalコンポーネントでも使えるようにするためのものです。

具体的には、今まではクラスコンポーネントでしか持つことができなかったstateやライフサイクルをFunctionalコンポーネントで利用できるようになります。

今までReactの様々な機能にアクセスできるクラスコンポーネントと違い、一切のアクセスが許可されていなかったFunctionalコンポーネントをReactの機能へ接続(Hooks into)するという意味で、Hooksと呼ぶらしいです。
#なぜHookを使うのか
察しの良い皆さんならこう思ったはずです。

「stateやライフサイクルメソッドが使いたいならクラスメソッド使えば良くね？」

確かに一理あります。

しかし、クラスコンポーネントには以下で示すような問題がありました。

+ 処理が散らばりやすい
+ thisを使いたくない
+ 複数のライフサイクルメソッドに処理がまたがるのが嫌だ
+ そもそもクラスコンポーネントの構文が複雑
+ stateの扱い方が複雑

この中のいくつかの問題点を、さらに深く解説していきます。

##処理が散らばりやすい
Reactを書いたことがある皆さんなら共感頂けると思いますが、クラスコンポーネントはメソッドをいくつも実装できるが故に処理が散り散りになりやすいんですよね。

子供のコンポーネントで行われる処理を、親のクラスコンポーネントのライフサイクルに定義して使いたくなりますよね。

具体例で話すなら、例えば`人間コンポーネント`を定義して、それに子供として`ハサミコンポーネント`を渡したとします。

このハサミコンポーネントの前に`紙が存在するとき`に、ハサミコンポーネントの`切断`という機能を実装したいとします。

人間コンポーネントをクラスコンポーネント、ハサミコンポーネントをFunctionalコンポーネントだとすると、`紙`はstateを持つ人間コンポーネントで管理することになりますし、紙の状態に応じた処理(ここでは切断する)もライフサイクルを持つ人間コンポーネントの中で書くことになりそうです。

子供のコンポーネントがハサミコンポーネントのみならまだしも、他の様々なコンポーネントのstateやライフサイクルも人間コンポーネントで管理することになると、非常に煩雑になりそうですよね。

そもそも、`切断する`という処理はハサミコンポーネントの中の処理であるので、当然の思考としてハサミコンポーネントの中で管理するのが良さそうです。

また、`紙`というstateも、紙の状態に応じたライフサイクルを用いた処理も、人間コンポーネントではなくハサミコンポーネントで管理するべきですよね。

ここでハサミコンポーネントをクラスコンポーネントにしてしまっても良いのですが、それだと根源的な解決になりません。

そもそも、`ひとつの機能はひとつの場所に`という原則を守って書くことを強制してしまった方が良さそうです。

そこで導入されたのがHookであり、Functionalコンポーネント自体にstateやライフサイクルを管理させるとうものです。

##thisを使いたくない
Javascriptにおけるthisは、他の言語におけるthisとは違う挙動をします。

詳しくは以下の記事を御覧ください。

[JavaScriptの「this」は「4種類」？？](https://qiita.com/takeharu/items/9935ce476a17d6258e27)

[JavaScript の this を理解する多分一番分かりやすい説明](https://qiita.com/takkyun/items/c6e2f2cf25327299cf03)

つまり、簡単に書くと`thisの使い方めっちゃむずい`ということです。

こんなものはトラブルの元です。

できるだけ使わないようにしようという動きも多く、そのためクラスコンポーネントはできるだけ使いたくないと思う人も多いようです。

## 複数のライフサイクルメソッドに処理がまたがるのが嫌だ
クラスコンポーネントのライフサイクルメソッドは、時間の流れで処理を分割します。

そうすると、同じような機能が複数のライフサイクルメソッドに跨ってしまうことがありますよね。

そのように記述するよりも、`同じ機能は同じ場所`と言う方が分かりやすいと考える人も多いようです。ちなみに私もそう思います。

#React-Hooksの実装
それでは実際にHooksを実装してみましょう。

##Hooksでstateの管理
まず、Hooksでstateの管理をしていきます。

HooksはFunctionalコンポーネントにおけるstateの管理やライフサイクルメソッドの実装に用いるんでしたね。

Hooksでstateを用いるときは、`useState`というメソッドを使います。

実際にコードで確認してみましょう。

今回は、ScissorsコンポーネントというFunctionalコンポーネントを作成して、それを親コンポーネントであるAppコンポーネントから呼び出します。

そのScissorsコンポーネントに`cutting`とうstateを持たせて、ボタンを押すことで変化させるという機能を実装します。

以下がコードです。

```App.jsx
import React from 'react';
import Scissors from './Scissors'

const App = () => {

  return(
    <div>
      <Scissors />
    </div>
  )
}
export default App
```
これはシンプルにScissorsコンポーネントを呼び出しているだけですね。以下がそのScissorsコンポーネントです。

```Scissors.jsx
import React, { useState } from 'react';

const Scissors = () => {
    const [cutting, changeCutting] = useState("NoCutting");
    return(
        <div>
            <h1>{cutting}</h1>
            <button onClick={() => changeCutting("YesCutting!")}>change </button>
        </div>
    )
}

export default Scissors
```

それではHooksの部分を解説していきます。

以下の部分でuseStateをインポートしています。

```.jsx
import React, { useState } from 'react';
```

これでインポートすることができました。

次の部分が、useStateを使う上で肝となる部分です。以下のコードです。

```.jsx
const [cutting, changeCutting] = useState("NoCutting");
```

それでは解説します。

`cutting`がstateであり、`changeCutting`がstateを変更させる関数です。ちなみに、この`changeCutting`に引数を渡して実行すれば、`cutting`の値がその引数に渡した値に変化します。

つまり、このuseState関数は、`state`と`stateを変更させる関数`を同時に定義していると考えることができますね。

クラスコンポーネントでは、constructorの部分で`this.state = {}`という感じにstateを定義し、`setState`を用いてそのstateを変更していたと思います。

それでは、`useState`の引数の部分は何を意味するのでしょうか。

正解は、`stateの初期値`になります。

つまり、上のコードは`cutting`というstateを作成し、その初期値に`NoCutting`を渡し、それと同時にそのstateを変更させる関数である`changeCutting`を作成したことになります。またこの`changeCutting`は、実行したときに`cutting`の値を引数に指定した値に変更させる関数になります。

以下のコードで、ボタンをクリックしたときにこの`changeCutting`を実行しています。

```.jsx
<button onClick={() => changeCutting("YesCutting!")}>change </button>
```

buttonタグのonClickにアロー関数として`changeCutting`を実行したものを渡しています。

onClickはボタンをクリックしたときに引数として渡された関数を実行するという機能なので、このように関数そのものを渡します。

実際にこのReactアプリの挙動を見てみましょう。

![temp3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/4c8d08e8-47f7-15d5-eec9-71297b01dd92.gif)

ここまでで、Hooksによるstate管理は終わりです。

##Hooksによるライフサイクルの管理
Hooksによるライフサイクルメソッドの代替として、`useEffect`メソッドがあります。

以下の三つのメソッドを代替することができます。

+ coponentDidMount()
+ componentDidUpdate()
+ componentWillUnmount()

軽く解説します。

###componentDidMountについて
componentDidMountはマウントが行われた直後に実行されるメソッドです。Ajaxを使ったデータフェッチ(初回)やイベントリスナのセットなどを行います。

###componentDidUpdateについて
componentDidUpdateはstateの更新が行われた直後に行われるメソッドです。具体的には、stateが更新され、その後にrenderが走った後に呼び出されます。

`stateがある閾値を超えたときに別の動作をするようにしたい`ときなどに使うと便利ですね。


###componentWillUnmountについて
componentWillUnmountは、コンポーネントが破棄される直前に呼び出されます。

具体的には、イベントリスナーを解除してメモリを開放するときなどに利用されます。

それでは、実際に`useEffect`メソッドを用いてこれらのライフサイクルメソッドを実装してみましょう。

#useEffectメソッドの実装
まず、最初にuseEffectメソッドの使い方解説を行います。

以下の記事を参考にしました。

[【React】useEffectの第２引数って？](https://qiita.com/k-penguin-sato/items/9373d87c57da3b74a9e6)

##第一引数のみ

第二引数を空っぽにすると、第一引数に指定したコールバック関数がrender毎に実行されます。

`componentDidUpdate`と同じタイミングで呼ばれることになりますね。

```.jsx
useEffect(() => {
  console.log("render")
});
```

しかし、これは公式のリファレンスで推奨されていない書き方なので、使わないようにしましょう。

##第二引数を与える

###空の配列が渡されたとき

```.jsx
useEffect(() => {
  console.log('mounting')
}, [])
```

第二引数に空の配列が渡された場合、マウント時のみ、第一引数に渡されたコールバック関数を実行します。

Reactはrenderが呼ばれるたびに`第二引数の値がrender前とrender後に変化したかどうか`を確認します。

その時、変化していた場合にのみ第一引数に設定したコールバック関数を実行します。

今回は、第二引数に空の配列を指定しているため、マウント時のみ第一引数のコールバック関数が走るようになります。

`componentDidMount`と同じタイミングになります。


###第二引数の配列に値が渡された場合
第二引数に値の配列が渡された場合、`renderの前後で値が変化した場合`に第一引数のコールバック関数が呼ばれます。


```.jsx
const [boolean, changeBoolean] = useState(true)
useEffect(() => {
  console.log('changed')
}, [boolean])
```

この場合、第二引数に渡した`boolean`の値が変更されるたびに第一引数に渡したコールバック関数が呼ばれるようになります。


###マウント時とアンマウント時のみ実行
useEffectメソッドにおいては、第一引数のコールバック関数内においてreturnを行うと、そのreturnの中の処理がアンマウント時に実行されるようになります。

以下のコードです。

```.jsx
useEffect(() => {
  console.log("render")
  return () => {
    console.log("Unmounting!")
  }
}, []}
```

第二引数に空の配列を渡しているので、render毎に実行されることはありません。

つまり、`console.log("render")`の部分がマウント時のみ実行されるようになります。

また、return後の関数が、アンマウント時に実行されるようになります。

#終わりに
今回の記事はここまでになります。

お疲れさまでした。

#参考

[日本一わかりやすいReact入門#8...React Hooksでstateを扱おう](https://www.youtube.com/watch?v=Vzvbke_CLAs)

[React Hooks超入門](https://qiita.com/ossan-engineer/items/99739b60b391c8013928)

[最近Reactを始めた人向けのReact Hooks入門](https://sbfl.net/blog/2019/11/12/react-hooks-introduction/)