React入門 未経験から1週間でReactをマスターする #03. Class ComponentsとFunction Componentsの書き方

# 目次

[1. Reactの新規プロジェクトの立ち上げ](https://qiita.com/yassun-youtube/items/2ae26050efd2133c2286)
[2. コンポーネントのプロパティ(props)とステート(state)](https://qiita.com/yassun-youtube/items/ca91e2f9905fb8ca62d0)
[3. Class Components と Function Components] (https://qiita.com/yassun-youtube/items/2ed8601e4fa477726705)<font color="Red">←今ここ</font>
[4. 条件分岐 (if) と繰り返し (loop)](https://qiita.com/yassun-youtube/items/9474b1681958e2ab0f25)
[5. フォームと親子間のデータのやり取り](https://qiita.com/yassun-youtube/items/545e7d9c98fe919dc394)
[6. コンポーネントのライフサイクル](https://qiita.com/yassun-youtube/items/372464404ae6855e6d78)
7. スタイル (準備中)
8. Higher-Order Component (準備中)
9. Portalを利用したモーダル (準備中)
10. refによるエレメントの取得 (準備中)
11. Contextを利用したテーマの変更 (準備中)

# 今回の学習内容

今回は、

- Class Components , Function Components の書き方についての理解
- Class Componentsでのコンポーネントの書き方

をやっていきます。


# YouTubeでの解説動画

YouTubeでも解説しています。
動画で確認したい方はこちらもどうぞ。
[【YouTube動画】 未経験から1週間でをマスターするReact入門 #03. Class ComponetnsとFunction Componentsの書き方](https://youtu.be/ve85ejcYiZ0)
[![【YouTube動画】 未経験から1週間でをマスターするReact入門](https://img.youtube.com/vi/ve85ejcYiZ0/0.jpg)](https://youtu.be/ve85ejcYiZ0)

# この記事のソースコード
ソースコードはGitHubで公開しています。

https://github.com/yassun-youtube/ReactTutorial

ブランチが違うので注意してください↓
![スクリーンショット 2020-11-14 1.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/7d05289c-8efd-3ca2-29d4-03476b283ae0.png)

今回のコミット一覧↓
![スクリーンショット 2020-11-14 1.32.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/ea47d3e0-ff45-6007-8333-bdafec989df1.png)


# Class Components

少しずつReactの書き方がわかってきたところで、 `Class Components` と `Function Components` の話をします。

Reactでのコンポーネントの書き方に、 `Class Components` と `Function Components` があります。
`Function Components` は、本入門で紹介してきた書き方で、 `function` を定義するとそれがコンポーネントになりました。
`Class Components` は、 JavaScript のクラスを記載することで、コンポーネントを定義する書き方です。

今は `Function Components` の書き方が使われることが多くなってきていると思いますが、 `Class Components` の書き方もまだまだ使われているため、 `Class Components` の書き方を学んでおく必要があります。

今回は、 `App.js` を `Class Components` で書き直してみます。


# ブランチの作成

本入門では、すべてのコードを `Class Components` で記載したものを別ブランチで管理します。

`class-components` ブランチを作成しましょう。

```bash
git checkout -b class-components
```

# App.js の Class Components 化

まず、一番単純なコンポーネントにしてみます。

```jsx:src/App.js
// 全体的に書き直し
import React from 'react';

class App extends React.Component {
  render() {
    return (
      <div>クラスコンポーネントにしてみました。</div>
    )
  }
}

export default App;
```

もともと `function` だったものが、 `class` に変わっていることがわかると思います。
`function` だったときは、その `return` で `<div>` を返していましたが、 `Class Components` では
`render` 関数の返り値が表示するものになります。

画面表示を確認してみましょう。

![スクリーンショット 2020-10-31 22.12.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/50330558-4edf-5751-894e-4e7a8e8ee74a.png)

このようになりました。


# List.js の Class Components 化

`List.js` も同じ様に変更します。

```jsx:src/List.js
import React from 'react';

export class List extends React.Component {
  render() {
    const { title } = this.props;

    return (
      <div>
        <h4>{ title }</h4>
        <div>リストです</div>
      </div>
    )
  }
}
```

`List` コンポーネントでは、 `props` の `title` という値を利用していました。
`Class Components` では、 `this.props` に `props` が入っています。 
`Function Components` では、下記のように関数の引数に入っていましたね。

```jsx
const List = ({ title }) => {}
```

## App.jsから List.js を呼び出す

```jsx:src/App.js
import React from 'react';
import { List } from "./List";

class App extends React.Component {
  render() {
    return (
      <div>
        クラスコンポーネントにしてみました。
        <List title="取り扱い言語一覧" /> // 追加
      </div>
    )
  }
}

export default App;
```

これは以前行った変更と同じですね。
画面表示は下図のようになります。


![スクリーンショット 2020-10-31 22.22.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/eca4a1c7-d215-d181-3d11-5faf45cdc73a.png)

---

# Class Components での state の利用

`App.js` で `state` を利用するようにコードを修正してみます。

```jsx:App.js
import React from 'react';
import { List } from "./List";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { description: 'クリック前の表示' }
  }

  changeDescription() {
    this.setState({
      description: 'クリック後の表示です。'
    })
  }

  render() {
    const { description } = this.state;
    return (
      <div>
        { description }
        <List title="取り扱い言語一覧" />
        <button onClick={() => this.changeDescription()}>ボタン</button>
      </div>
    )
  }
}

export default App;
```

同じことができるコードなのですが、 `Function Components` より少し長いですね。
画面にはボタンが表示されていて、クリックすると下記のように表示されます。

![スクリーンショット 2020-10-31 22.40.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/03671a65-293b-4229-7dae-5660f5a2686d.png)

## コードの解説

`Class Components` では、 `state` の初期値は constructor で定義します。

```jsx
  constructor(props) {
    super(props);
    this.state = { description: 'クリック前の表示' }
  }
```

ここですね。 `constructor` は `props` を引数にとり、それを `super(props)` で渡す必要があります。
その後、 `state` を初期化しています。
初期化のときは、 `this.state = {}` と `=` を使います。

次に `changeDescription` を見ていくと、

```jsx
  changeDescription() {
    this.setState({
      description: 'クリック後の表示です。'
    })
  }
```

となっていて、 `setState` という関数で `state` を更新していることがわかります。
ここで注意して欲しいのが、これは `this.state = ` では動きません。

Reactでは、ステートの更新を明示的に関数で呼び出してやる必要があります。 `setState` を呼ばれると、Reactがコンポーネントの表示を更新する必要があるとわかるわけですね。

最後に、 `button` に対しての `onClick` イベントを追加している部分を見ていきます。

```jsx
<button onClick={() => this.changeDescription()}>ボタン</button>
```

ここでは、 `onClick` で `changeDescription` メソッドを呼び出しています。

ここで注意してほしいのが、 `onClick` で `changeDescription` 関数の参照だけを渡すとエラーになることです。

```jsx
<button onClick={this.changeDescription}>ボタン</button>
```

このように記載を変えると、ボタンを押すとエラーになります。

![スクリーンショット 2020-10-31 22.37.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/3d9afa58-b53e-e000-866a-2792024182af.png)

参照だけ渡すと `this` の罠に捕まってしまうので、ちゃんとこのインスタンスが参照されるように意識しましょう。

ちなみに、 `bind` で `this` を固定してもちゃんと動きます。
こちらの書き方のほうが好きという方はこちらの書き方を利用しても良いです。

```jsx
<button onClick={this.changeDescription.bind(this)}>ボタン</button>
```

# 今日やったこと

今日やったことをまとめます。

## Class Components と Function Componentsの違い

### 一番単純なコンポーネント
```jsx
class ClassComponent extends React.Component {
  render() {
    return (
      <div>クラスです。</div>
    )
  }
}
```

```jsx
function FunctionComponent {
  return (
    <div>ファンクションです</div>
  )
}
```

### プロパティの違い


Class Componentsでは、

```jsx
this.props
```

Function Components

```jsx
function FuncCompo(props) {}
```

### ステートの違い

#### 初期化
Class Components

```jsx
constructor(props) {
  super(props);
  this.state = { test: initialValue };
}
```

Function Components

```jsx
const [test, setTest] = useState(initialValue);
```

#### ステートの変更

Class Components

```jsx
this.setState({ test: value })
```

Function Components

```
setTest(value);
```


# おわりに

これで入門 その2と同様のコードを `Class Components` の書き方で書くことができました。
今後の入門は、基本的に `Function Components` の書き方で書いていきますが、 `Class Components` での書き方も解説していきます。

# 次の記事

React入門 未経験から1週間でReactをマスターする #04. 条件分岐(if)と繰り返し(loop)
https://qiita.com/yassun-youtube/items/9474b1681958e2ab0f25