【React】クラスコンポーネント /関数コンポーネントの違いと使い分け。なぜ 関数コンポーネントが好まれるのか。

# はじめに
どうも[シュータ](https://twitter.com/syuta_sugawara)といいます！
2019年、 React 16.8のリリースに伴いHooksが導入され、
stateやlife cycle methodを使用する際はClass Componentを使用した方が良いという判断が実情に合わなくなってしまったように思います。
この記事では今一度、クラスコンポーネントと関数コンポーネントの違いを明らかにしつつ、Hooksの導入に伴いどう変化したか、
そして関数コンポーネントが好まれやすいのは何故かという理由を記載します。

# 関数コンポーネントとクラスコンポーネント

まず関数コンポーネントとクラスコンポーネントで
シンプルなコンポーネントを作成した例を示します。


```jsx:関数コンポーネント

function Welcome(props) {
  return <h1>Hello, {props.name} </h1>;
}

```

こちらは基本的なjavascriptの関数と同様です。
propsを受け取り、使用することが可能です。



```jsx:クラスコンポーネント

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

```

こちらはReactのCompoentクラスを継承しています。
クラスコンポーネントでもpropsを受け取り
使用することは可能です。

# Hooks導入以前の関数コンポーネントとクラスコンポーネントの主な違い

クラスコンポーネントでは関数コンポーネントと異なり、コンポーネント内で下記の二つを使用することができます。

- state(状態管理)
- Lifecycle method


### stateの例

```jsx

class Welcome extends React.Component {
  constructor(props){
    super(props)
    this.state = {
    name: "hoge"
    }
  }
  render() {
    return <h1>Hello, {this.state.name}</h1>;
  }
}

```

### Lifecycle methodの例
詳しくは[こちら](https://reactjs.org/docs/react-component.html)をご覧ください。

```jsx

class Welcome extends React.Component {
  constructor(props){
    super(props)
    this.state = {
    name: "hoge"
    }
  }

　componentDidMount() {
   this.setState({name:"fuga"})
  }
　
  render() {
    return <h1>Hello, {this.state.name}</h1>;
  }
}

```

# Hooks導入後
HooKs導入前は関数コンポーネントとクラスコンポーネントは
前述のような違いがありましたが
Hooksの登場により、関数コンポーネントでも
状態管理やライフサイクルの機能を使用できるようになりました。
そしてそれらはクラスコンポーネントで記述するよりも
簡潔に書くことが可能です。

###状態管理

```jsx:Hooksを利用した関数コンポーネントで状態管理する例


import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

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

```


```jsx:同様のコンポーネントをクラスコンポーネントで書いた場合

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>
    );
  }
}

```

###ライフサイクル

```jsx:Hooksを利用した関数コンポーネントでライフサイクルメソッドを使う例

import React, { useState, useEffect } from 'react';

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

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

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

```


```jsx:同様のコンポーネントをクラスコンポーネントで書いた場合

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>
    );
  }
}

```

# なぜ関数コンポーネントが好まれるか

- コードが簡潔にかける

これまでみてきたように
関数コンポーネントで記述することによってより見通しの良いコードがかけることに気付いていただけたと思います。

- Viewからの複雑さを排除することも可能となる

これまで示した例だけでなく、データフロー全体の設計からの観点となりますがコンポーネントになるべく状態を持たせない設計や、view以外ファイルにAPI通信などの副作用を局所化させる設計を行うことより
viewの責務を軽くすることも可能です。
将来的にReact以外のライブラリ、フレームワークを使用することになった際も乗り換えやすくなることが期待できます。

#　最後に

読んでくださった方ありがとうございました！

誤字脱字・間違い等ございましたら、指摘して頂けますと幸いです！
また、説明にわかりづらい点がございましたら、改善致しますのでぜひコメントください。


# reference 
https://reactjs.org/