TypescriptでReactを学ぶ(コンポーネントとPropsについて)

# はじめに
TypescriptでReactの構成や記述を説明します．今回の記事ではコンポーネントとPropsについて書いています.基本的なことを書いているので初心者向け．
コードを載せていますが，アプリを作るわけではないため，ちょっと動かしてみたいだけなら[CodeSandbox](https://codesandbox.io/)等のWeb上で動かしてみるといいと思います．
もし，自分のPCで動かしたいならば，下記のサイトを参考にして環境設定をしてみてください．

[Node.jsをバージョン管理しながらインストールするまでの道](https://qiita.com/wdkkou/items/868f4e71fda092ecb87e)
[Reactを始める前にざっくり理解してcreate-react-appを動かす](https://qiita.com/wdkkou/items/379d8c9f95dbec2e160a)




# 関数コンポーネント　クラスコンポーネント
Reactはそれぞれのコンポーネントを組み合わせて構成されています．
コンポーネントは関数コンポーネントとクラスコンポーネントの２種類存在します．以前までは，クラスコンポーネントはStateを持てるが，関数コンポーネントはStateが持てない違いがあり，必要に応じて使い分けていたらしい．しかし，現在は，Hooksと呼ばれるものは導入されて，関数コンポーネントもStateを持てるようになりました．(Stateやhooksについては別の記事で説明出来たらいいな．)
このような背景やReactの設計思想などの様々な理由から，コンポーネントを作る際には関数コンポーネントで作ることが推奨されています．
今回の記事では，はじめのクラスコンポーネントの説明のためのclass.tsx以外のコンポーネントは関数コンポーネントで書いています．

### 関数コンポーネントのほうがいい様々な理由
[関数コンポーネントはクラスとどう違うのか?](https://overreacted.io/ja/how-are-function-components-different-from-classes/)
[Functional Component と PureComponentの違い・使い分け](https://qiita.com/daikoncl/items/a3806d8a8bf35f086487)
[Stateless な React Component の記法をまとめてみた](https://qiita.com/kotaroito/items/e36ebac185b6b1d8538d)
### index.tsx
トップレベルで呼び出されるコンポーネント．htmlファイルのrootタグに紐付けられている．このファイルではapp.tsxファイルのコンポーネントをインポートして，表示しているだけ．

```TSX:index.tsx
import React from "react";
import { render } from "react-dom";

import App from './app';

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

```
### app.tsx
class.tsxとfunction.tsxファイルのコンポーネントをインポートしてAppコンポーネントに埋め込んでいます．このようにそれぞれで作成したコンポーネントを組み合わせて構成している．

```TSX:app.tsx
import React from "react";
import Hello1 from './class';
import Hello2 from './function';

const App: React.FC = () => {
  return (
    <>
    <Hello1 />
    <Hello2 />
    </>
  );
};

export default App;
```
### class.tsx
クラスコンポーネントで作成した場合のコンポーネント．ComponentをインポートしてHelloコンポーネントに継承している．renderメソッドで中身の部分を表示している．

```TSX:class.tsx
import React, { Component } from "react";
class Hello extends Component {
  render() {
    return (
      <>
        <h1> Hello World</h1>
        <div> クラスコンポーネントの場合</div>
      </>
    );
  }
}

export default Hello;
```
### function.tsx
関数コンポーネントで作成した場合のコンポーネント．
クラスコンポーネントより記述が少なくなっているのが見て分かる．返り値としてJSXを返して描画している．

```TSX:function.tsx
import React from "react";
const Hello: React.FC = () => {
  return (
    <>
      <h1> Hello World</h1>
      <div> 関数コンポーネントの場合</div>
    </>
  );
};

export default Hello;
```
# 実行画面

![コンポーネント 実行画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466520/a9bb3fbb-4cd2-c1a1-6b19-cec3e4a54a4f.png)

# Props
関数における引数に対応したもの．親コンポーネントから子コンポーネントに渡すデータで，子コンポーネントから親コンポーネントに渡すことは出来ない．読み取り専用のデータ．下記では，新たにコンポーネントを作成してPropsの使い方を見ていきます．App.tsxファイルを変更し，2つのファイルを追加します．

### app.tsx
props_example1.tsxとprops_example2.tsxファイルのコンポーネントをインポートしてAppコンポーネントに埋め込んでいます．それぞれデータをPropsとしてそれぞれの子コンポーネントに受け渡している．

```TSX:app.tsx
import React from "react";
import Hello3 from "./props_example1";
import Hello4 from "./props_example2";

const App: React.FC = () => {
  return (
    <>
    <Hello3 name={"hoge"}/>
    <Hello4 name={"hoge"} age={500}/>
    </>
  );
};

export default App;
```
### props_example1.tsx
これは，名前のデータを受け取り，その情報を表示するコンポーネントになります．FC<>の中にコンポーネントのPropsの型を書き，引数として{name}を受け取ります．
関数の引数は{}をつけずにnameとするとエラーになるので気をつける．理由はなんでだろう? コンポーネントの受け渡しであるPropがオブジェクト型であるためっぽい．


```TSX:props_example1.tsx
import React, { FC } from "react";

const Props: FC<{ name: string }> = ({ name }) => {
  return (
    <>
      <h1> Props の受け取り </h1>
      <div> hello {name}</div>
    </>
  );
};

export default Props;

```
### props_example2.tsx
名前と年齢のデータを受け取り表示するコンポーネント．複数のデータを受け取る場合には，インターフェース等を定義し，Propsの型を指定すればいい．

```TSX:props_example2.tsx
import React, { FC } from "react";
interface profile {
  name: string;
  age: number;
}
const Props: FC<profile> = ({ name, age }) => {
  return (
    <>
      <h1> Props の受け取り </h1>
      <div>
        hello {name}, {age} 歳
      </div>
    </>
  );
};

export default Props;
```
#実行画面
![Props 実行画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466520/25e2a5fb-bd88-9cff-03ea-396ac411af29.png)

# まとめ
とりあえず，Typescriptでの基本的なコンポーネントとPropsの使い方を学んだ．次は，Stateについての記事を書きたいと思います．

# 参考サイト
[関数コンポーネントはクラスとどう違うのか?](https://overreacted.io/ja/how-are-function-components-different-from-classes/)
[Functional Component と PureComponentの違い・使い分け](https://qiita.com/daikoncl/items/a3806d8a8bf35f086487)
[Stateless な React Component の記法をまとめてみた](https://qiita.com/kotaroito/items/e36ebac185b6b1d8538d)
[コンポーネントとProps](https://ja.reactjs.org/docs/components-and-props.html#___gatsby)
[React on TypeScript 事始め](https://qrunch.net/@jintz/entries/KCNg0YDCe21PeTyt)