今更だけど「Function Component」 と 「Class Component」の違いをざっくり。

Reactを勉強中にこんがらがったのでメモ

Reactのcomponentを作成する際には大きく２種類ありそれが

**・Function Component**
**・Class Component**

現在はFunction Componentを使うことを推奨されており、その理由についても調べてみました。

##そもそも***Component***とは?
Reactでは複雑なUIをComponentという小さな部品を組み合わせて実現することが可能
Railsやってた人なら部分テンプレートをイメージするといいかも。

適度な粒度のコンポーネントに分けることで可読性と再利用性というメリットがある。
この適度な粒度に関してはAtomic Designという概念もある。

【参考】[Atomic Designを使ってReactコンポーネントを再設計した話](https://blog.spacemarket.com/code/atomic-design%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6react%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%82%92%E5%86%8D%E8%A8%AD%E8%A8%88%E3%81%97%E3%81%9F%E8%A9%B1/)




####コンポーネントの主な登場人物
***・JSX***
***・Props***
***・State***

##JSX
JSXはhtml埋め込めるやつというざっくりとした考えの方もいるのではないでしょうか？
（自分もそう思っていました。 ）

正確にはJSXはJavaScriptに変換さています。

Babelでコンパイルするとわかりやすいです。（右が変換後）
<img width="1124" alt="スクリーンショット 2020-04-28 22.35.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/da9b243a-020d-be1f-dbb5-5467e3e768fe.png">

```javascript
return <div>Hello React</div>
```
の部分が変換されている↓

```javascript
return react.default.createElement("div", null, "Hello React");
```

見比べて見るとわかる通りJSXの方が記述量も少なく可読性も高いですね。


##Props
 -コンポーネントの性質を表すもので***不変***
 -親から子に情報を渡す



以下の二つの箱をpropsを使って再利用してみます。
![Yellow Black Beer Modern Father's Day Card (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/4877b30c-dc40-f664-3ee8-05455ee77185.png)


```javascript:Box.js
//子コンポーネント

import React from 'react';

const Box = props => {
  return ( 
    <div>{props.title}</div>
  );
};
export default Box;

```

```javascript:App.js
//親コンポーネント

import React from 'react';
import Box from './components/box'

export default App = () => {
  return (
    <Box title="Hello world" />
    <Box title="Good bye world" />
  );
};

```
オブジェクトスプレッド演算子を用いるとpropsを省略できる。

```javascript
//子コンポーネント

import React from 'react';

const Box = ({ title }) => {
  return (
    <div>{title}</div>
  );
};
export default Box;
```
※css省略

##State
-コンポーネントの状態を表すもので***可変***
-Stateを変更することで画面が更新される


##ここから本題

以前まではClass Componentでは***state、ライフサイクル***（componentDidMountなど）が使え、
Function Componentではそれらが使えないのが違いと言われていた。

しかし、現在では***Hooks***が導入されたことによりFunction Componentでも***useState、useEffect***などを使って、
Stateやライフサイクルに相当するものが使えるようになっている。

##Function Componentを使うメリット
-記述が短くなる
-動作も少し早くなると言われている。（未検証）

例)　引用（[React -ステートフックの利用法-](https://ja.reactjs.org/docs/hooks-state.html)）

```javascript:ClassComponent
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
```
```javascript:FunctionComponent
import React, { useState } from 'react';

function Example() {
  //state関数呼び出し
  const [count, setCount] = useState(0);
 
  return (
    <div>
      //ClassComponentではthis.state.countで呼び出す
      <p>You clicked {count} times</p>
      //すでにcountとsetCountを受け取っているのでthisは不要
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
```
useStateは関数内で使うのでかなりスッキリ書けます。

次に副作用フックを見てみましょう。
上述のコードにクリック回数を含んだカスタムのメッセージをドキュメントのタイトルに表示してみます。
例)　引用（[React -副作用フックの利用法-](https://ja.reactjs.org/docs/hooks-state.html)）


```javascript:ClassComponent
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

```

```javascript:FunctionComponent
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

```

少しReact触った人ならuseEffectフックはcomponentDidMount、 componentDidUpdate、 componentWillUnmountがまとまったものと言うのがわかりますね。


上述だとドキュメントのタイトルをセットしているだけですが、
データを取得したり、その他何らかの命令型の API を呼び出したりすることも可能

```javascript:
//東京都最新コロナ感染者を取得
//自分のアプリに実装したものを少し書き換えてます。冗長なところあれば教えてください。。🙇‍♂️

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Moment from 'moment';
import 'moment/locale/ja';

const DATA ='https://raw.githubusercontent.com/tokyo-metropolitan-gov/covid19/master/data/data.json';

function covidTokyo {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      const response = await axios.get(DATA);
      setData(response.data.patients_summary.data.slice(-1)[0]);
    } catch (error) {
      console.error(error);
    }
  };

  Moment.locale('ja');
  var dt = data['日付'];

  return (
    <div>
      【東京都】新型コロナ新規感染者数({Moment(dt).format('MMMDo')}
      <div> 
        +{data['小計']}名
      </div>
    </div>
  );
};
```
##結論
Hooksが導入されたことでコードの記述量といい可読性といいFunction Componentを使うことが推奨されている理由がわかったと思います。
ただ、ネットで落ちている情報などはClass Componentで書かれているものが多いので、
Class ComponentとFunction Component両方の知識は付けておくのがいいのかなと。

React駆け出しなので間違っているところなどあれば教えて頂けると嬉しいです🙇‍♂️🙇‍♂️