30分でReactの基礎を身体で覚える

2019-02-26
以前社内の勉強会用で作った物。
限定公開にしていたけど、そうする必要もないなと気づいて投稿します。

#目次
- はじめに
- コンポーネント思考
- 雛形
- stateとprops
- Lifecycle
- イベントハンドラ (clickイベント等)


##はじめに
この内容はかなりコンパクトにまとめてます。
細かい説明などは本やネットで拾えると思うのでReactの全体図を簡単に説明しますので、これを頭に入れてから教材を学べばあ〜なんか見たな〜って感じになると思ってくれたらいいなと思って作ってます。

Reactは基礎を抑えて使うだけならそんなに難しくないです。
ただ、

- 保守性だったりスマートな書き方だったり極めようとすると奥が深く色々なライブラリであったり、概念が存在する。
- Reactを取り巻く周辺環境が多く、難度を高める(Webpack、Babel、Redux、EsLint、HOC等)
- JSの知識が必要

なので今回は簡単な基本編で紹介します。

>導入は省略、以下見てください
>https://qiita.com/chibicode/items/8533dd72f1ebaeb4b614

##コンポーネント思考
まずは概念です。
通常のHTML、JS(jQuery)などでは一つのページにつきHTMLが1枚作ってそこに1ページ分のHTMLを書いていたと思います。
しかしReactや話題のVue.js、Angularではコンポーネントというもので細分化できるようになっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/f7b33d8b-46e2-f6b9-1a0b-1932b986eb68.png)

こういったページを

![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/243c2960-fc64-ef41-a41d-8e3b72ffa9c1.png)

このように細分化し
一つ一つパーツを作って組み立てていきます。

**このパーツをコンポーネントと呼びます。(細かくいうと違うんですがこう覚えておいてください。)**

実際のコンテンツでいうと以下の感じ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/5e760298-5bf2-591a-cc30-94c04a32eebe.png)

概要はこんな感じ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/d5b4bec4-c8c0-2b1c-ff88-5e95a5fa8766.png)


この**親でデータを取得→子で受け取ったデータを使ってHTML書く**という流れを覚えておいてください。


こうして作ったパーツによりそのパーツの再利用ができるようになります。

> Atomic Design
> この本が詳しく載ってます。
> https://www.amazon.co.jp/React%E9%96%8B%E7%99%BA-%E7%8F%BE%E5%A0%B4%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E7%9F%B3%E6%A9%8B-%E5%95%93%E5%A4%AA/dp/4839960496/ref=sr_1_2?ie=UTF8&qid=1535975798&sr=8-2&keywords=react


##雛形

上記をイメージしながら次に進みましょう。
Reactには雛形が存在し全ての構文はこの雛形にパーツをくっつけたイメージになるのでこれをまず覚えましょう
細かいことは気にせず何回も書いて体で覚えましょう 笑

雛形は2つです。
**Class Component(親)**と**Functional Component(子)**の2つです。


**Class Component**

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

class SampleName extends React.Component { // このSampleNameがコンポーネント名です。
  constructor() {                          // 頭は大文字で、ファイル名も同名に
    super();
    this.state = {
      sampleState: 'sample',
    }
  }

　// このスペースに諸々の処理を追加していく。

  render() {
    return ( // このreturnの中のHTMLのようなものををJSXと呼びこの中にJSXを書いていきます。
      <div>
        これはクラスコンポーネント!!!
      </div>
    )
  }
}

```


**Functional Component**

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

const SampleName = () => {
  return (
    <div>
      これはファンクショナルコンポーネント！！！
    </div>
  )
}

export default SampleComponent;
```



##stateとprops
上記でもちらほら出て来ましたが、みんなが「便利！」って必ずいう機能がこのstateとpropsになります。
stateはデータを貯めておくことができる場所、propsはstateが子コンポーネントな渡されてpropsという名前に変換された物ってな感じに捉えといて下さい。

注意点が

- classComponent => state,propsどっちも使える
- functionalComponent => propsのみしか使えない(propsは親から受け取る) 

- state => this.setState()で上書き保存ができる
- props => stateからのデータを受けるだけ、上書けるが保存はできない。

ここから最後まで以下のサンプルを使います。

```App.jsx

import React from 'react';
import NumberCount from './count';

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

  componentWillMount() { // lifecycle
    this.setState({
      count: this.state.count += 1,
    });
  }

  handleChange() {
    this.setState({ // this.setStateでstateを更新
      count: this.state.count += 1,
    });
  }

  render() {
    return (
      <div>
        <h1>フルハシプロジェクト</h1>
        <NumberCount
          count={this.state.count} //stateを子に渡す
          handleChange={this.handleChange}
        />
      </div>
    )
  }
}

export default App;

```

プラス別ファイルを作成します

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

const NumberCount = (props) => {
  return (
    <div>
      <p>ハシシが{props.count}個取れた</p>
      <button onClick={() => props.handleChange()}> + </button>
    </div>
  );
}

export default NumberCount;
```


**state**

- 最初に定義します

App.jsxの上に

```App.jsx
  constructor() {
    super();
    this.state = {
      count: 0,
    }
    this.handleChange = this.handleChange.bind(this);
  }
```

**stateの初期定義**
constructorとかはクラス構文の話になるので、今は呪文のように書いておいて大丈夫です。
大事なのは

`this.state = {
count: 0,
}
`
というところ。

ここでstateの初期値を定義します。

**子に渡す**
これをJSX内で子に渡します。
ただの値だけでなく関数も渡せます。

**子で展開**
次にNumberCount.jsxでpropsに変換されて入ってくるので受け取って各所に渡します。

**setStateでstateの更新**
onClickするとhandleChange関数が発火し、`this.setState`でstateが更新されます。
この際、setStateすると必ずrender関数も発火しレンダリングが一回され、値の表示が1から２に変わります。
これは大事なので覚えておいてください。
**setStateするとレンダリングが必ず走る。**です



##LifeCycle

Reactではコンポーネントのライフサイクルという概念が存在します。
これがまた便利なのです。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/229570/9be2ee16-5b8c-e978-3847-5748915467cc.png)


上記の例の
`componentWillMount`では最初にレンダリングされる前、つまり画面に表示される前に関数内を処理してから画面に映ります。
なので今のfreeC内ではこの中でAPIを叩いてデータを取ってくる処理がほとんどです。

他も使い所はありますがfreeCプロジェクトでは90%componentWillMountしか使ってないです。

> 余談ですが現在Reactのversionが16.4なのですが、v17からlifecycleが変わり、componentWillMount始めいくつかのlifecycleが非推奨となります。なのでアップグレードする際はお気をつけて！



##イベントハンドラ
jQueryとは違いますが非常に近い感覚で使うことができます。

NumberCount.jsxの
`<button onClick={() => props.handleChange()}>+</button>`
の部分がまさにそうです。
感覚的にわかりますよね？
このイベントハンドラは無数に用意されています。
なのでJSでよくある
`document.getElementById('buttton')`
`button.addEventListener(() => {})`
みたいな事はほぼしなくていけるくらいプロパティが揃ってます。

**一つ注意点があります。**

```App.jsx

  handleChange() {
    this.setState({ // this.setStateでstateを更新
      count: this.state.count += 1,
    });
  }

```

App.jsx内で上記を定義してますが、関数を定義する時は必ずconstructor内で
`  this.handleChange = this.handleChange.bind(this);`で紐づけてあげないといけません。
constructor内でこう書いてあげないとrender関数やその他の関数内で呼ぶことができません。
これはclass構文の性質上なのです。
constructor内で紐づけてあげると他の関数内でthis.~と呼ぶことができるようになります。
(他にも紐づける書き方はあるのですが、とりあえずはこれで覚えておいてください。)




##個人的に為になった文献など
**[本]**

https://www.amazon.co.jp/React%E9%96%8B%E7%99%BA-%E7%8F%BE%E5%A0%B4%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E7%9F%B3%E6%A9%8B-%E5%95%93%E5%A4%AA/dp/4839960496/ref=sr_1_2?ie=UTF8&qid=1535975798&sr=8-2&keywords=react

**[udemy]**
これよかったんですけど定価なんですよね。。。
https://www.udemy.com/react-redux-basic/

これもいいけど長い。。。
https://www.udemy.com/react-redux/

**[ネット]**
Reactのドキュメントはいいですよ
https://reactjs.org/

https://reactjs.org/docs/thinking-in-react.html