React始めました。(基本構文編)

# はじめに
おはようございます。こんにちは。こんばんは。
ワタタクです。
今回はReact.jsの基本的な書き方などを勉強していこうと思います。

**※この記事は初学者用かつ自分の勉強用で書いていきます。**

# JSXの基本
まずはJSXとはどのような物なのかみてみましょう。

```jsx
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        {/* コメントだよ。 */}
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}
```
ほぼHTMLですね。
でもいくつか決まり事があります。
## imgタグの注意点
``imgタグ``は、HTMLでは、``<img src='画像のURL'>``のように閉じタグが必要ありませんでした。
一方、JSXでは閉じタグが必要になります。``<img src='画像のURL' />``のように、タグの終わりにスラッシュ**「/」**を記述します。
## クラス名の指定
クラス名の指定は``className=""``

```jsx:例
<div className="hogehoge">
```

## JSXのコメント
JSXを``{/* */}``で囲むと、その部分はコメントになります。

# JavascriptとJSX

```jsx
function App() {
  {/* Javascriptの範囲*/}
  const hello = "Hello React";

  return (
    {/* JSXの範囲*/}
    <p>
      {hello}
    </p>
  );
}
```
このようにreturnの外にJavascriptを記述します。
JSXに変数などを埋め込むときは``{hello}``のようにします。

## JSX内でのループ
``map()``を使います。

```jsx
import React from 'react';

function App() {
  const lists = [1,2,3,4,5,6,7,8,9,10];

    return (
      <>
      {lists.map((list, key) => {
        return <p key={key}>{list}</p>
      })}
      </>
    )
}

export default App;
```
このように配列に格納されている値の数をレンダリングしたいときなんかに使います。
## JSX内での条件分岐
### 即時関数

```jsx
import React from 'react';

function App() {
  const isMorning = false
    return (
      <>
      {(() => {
          if (isMorning) {
            return <span>Good morning</span>
          } else {
            return <span>Hello</span>
          }
        })()}
      </>
    )
}

export default App;
```
### 三項演算子
JSX内で条件分岐を行う場合は上で紹介した`即時関数`を使うより、`三項演算子`を使うのが一般的です。

```jsx
import React from 'react';

function App() {
  const isMorning = false
    return (
      <>
      {isMorining ? <span>Good morning</span> : <span>Hello</span>}
      </>
    )
}

export default App;
```

三項演算子を使う方がシンプルに書けますねw
- `if(変数)　{~} else {~}` => `変数 ? ~ : ~`
- `if(変数)　{~}` => `変数 && ~ `

# イベント
イベントを用いると、「何かが起きたときに、処理を実行するように指定」することができます。
## onClickイベント

```書き方
<button onClick={() => { 処理 }}></button>
```
# 関数型コンポーネントとクラス型コンポーネント
## 関数型コンポーネント
これまで書いてきたものは関数型コンポーネントと呼ばれ、状態**(state)**を持ちません。
### TIPS①
デフォルトでは``function 関数名 { }``という書き方で書いていますが、下記の書き方がよろしいでしょう。

```
const 関数名 = () => {
  /* Javascriptの範囲 /*
  return (
    {/* JSXの範囲/*}
  )
}
```
### TIPS②
関数型コンポーネントだろうがクラス型コンポーネントだろうが
``import React from 'react';``して、最後に``export default 関数名 or クラス名``を記述する。

## クラス型コンポーネント
一方こちらのコンポーネントでは状態**(state)**を持つことができます。
classの構文を使う場合、``React.Component``クラスを継承してコンポーネントを定義します。

```
class クラス名 extends Resct.Component {
  /* Javascriptの範囲 /*
  render() {
    return (
      {/* JSXの範囲/*}
    );
}
```
# stateの定義と表示
stateは、constructorの中で、オブジェクトとして定義します。
ここで定義したオブジェクトがstateの初期値となります。
その他の部分の、「constructor(props)」や「super(props);」といった処理はいつも同じ記述をするため、定型文として覚えておけば大丈夫です。

<font color="red">※``App.js``を``App.jsx``に変更してください。そして今後コンポーネントを作るときは``jsxファイル``で作ってください。</font>

```jsx:App.jsx
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {hello: "こんにちは"}
  }
  render() {
      return (
        <div>
          <h1>{this.state.hello}</h1>
        </div>
      )
  }    
}
```
# stateの変更
``this.setState({プロパティ名: 変更する値})``とすることで、指定されたプロパティに対応するstateの値が変更されます。

```jsx:App.jsx
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {hello: "こんにちは"}
  }
  render() {
      return (
        <div>
          <h1>{this.state.hello}</h1>
          <button onClick={() => {this.setState({hello: "おはようございます"})}}>おはようございます</button>
          <button onClick={() => {this.setState({hello: "こんにちは"})}}>こんにちは</button>
        </div>
      )
  }    
}
```
# メソッド
上の例のclickイベントの処理をメソッド化します。

```react:例
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {hello: "こんにちは"}
  }

  click(hello) {
    this.setState({hello: hello})
  }

  //click = (hello) => {
    //this.setState({hello: hello})
  //}

  render() {
      return (
        <div>
          <h1>{this.state.hello}</h1>
          <button onClick={() => {this.click("おはようございます")}}>おはようございます</button>
          <button onClick={() => {this.click("こんにちは")}}>こんにちは</button>
        </div>
      )
  }    
}
```

# コンポーネントを分ける
今までは``App.js``だけのレンダリングでしたが、実際大きなアプリケーションになると
コンポーネントの中にコンポーネントといったように複数のコンポーネントが組み合わさって一つのアプリケーションを生成していくので、ここではそのやり方を解説していきます。
``srcフォルダ``の中に``conponents/Child.js``を作成して下さい。

```jsx:Child.jsx
import React from 'react';

const Child =　() => {
    return (
        <div>
            <h2>子コンポーネント</h2>
        </div>
    )
}

export default Child
```
用意ができれば、``App,js``上で呼び出します。

```jsx:App.jsx
import React from 'react';

import Child from './conpoments/Child';  //←追加

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hello: "こんにちは", 
      count: 0
    }
  }

  click(hello) {
    this.setState({hello: hello})
  }

  //click = (hello) => {
    //this.setState({hello: hello})
  //}

  
  render() {
      return (
        <div>
          <h1>{this.state.hello}</h1>
          <button onClick={() => {this.click("おはようございます")}}>おはようございます</button>
          <button onClick={() => {this.click("こんにちは")}}>こんにちは</button>

          <Child />{/* ←追加 */}
        </div>
      )
  }    
}

export default App;

```

# データ送受信
<font color="red">※``App.js``を**親コンポーネント**,``Child.js``を**子コンポーネント**と呼ぶことにします。</font>

## 親コンポーネントから子コンポーネントにデータを渡す。
``props``を使います。

例えば、先ほどの例で行くと

```jsx:App.jsx
import React from 'react';

import Child from './conpoments/Child';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      hello: "こんにちは", 
      count: 0
    }
  }

  click(hello) {
    this.setState({hello: hello})
  }

  //click = (hello) => {
    //this.setState({hello: hello})
  //}
  render() {
      return (
        <div>
          <h1>{this.state.hello}</h1>
          <button onClick={() => {this.click("おはようございます")}}>おはようございます</button>
          <button onClick={() => {this.click("こんにちは")}}>こんにちは</button>

          <Child name={"hoge"}/>{/* ←追加 */}
        </div>
      )
  }    
}

export default App;

```

```jsx:Child.jsx
import React from 'react';

const Child = (props) => {
    return (
        <>
            <h2>子コンポーネント</h2>
            <p>渡されたデータ：{props.name}</p>
        </>
    )
}

export default Child
```
このように親で、``<子コンポーネント プロパティ名 = 値>``でデータを渡せ、子コンポーネント側で``props.プロパティ名``で親コンポーネント値を取得
できます。
<font color="red">子コンポーネントに引数として``props``を持たせてあげることを忘れずに！！</font>

# ライフサイクル
ライフサイクルにはまず、大きく分けて3つの期間があります。それぞれ順に
``Mounting``、``Updating``、``Unmounting``と呼ばれ、コンポーネントの準備期間、表示期間、破棄期間となっています。
UIにコンポーネントが描画されるまでの準備期間。1日に例えると夜明け前まででしょうか。

- componentDidMount()

1度目のrenderが呼ばれた後に1度だけ呼ばれるメソッドです。この時点ではまだUIに表示されていません。データをフェッチしたり、アニメーションやタイマーをセットする場合はここで行います。このメソッドからはDOMが作成されていますが、直接のDOM操作などライフサイクルを外れる処理は原則避けましょう。
##Updating
UIにコンポーネントが表示されていて、基本的にユーザーが操作できる期間。1日に例えると昼の活動時間帯。
使用できるメソッド:

- componentDidUpdate()

第一引数に1つ前のprops、第二引数に1つ前のstate、第三引数にsnapshotが入ってきますが、必要なければ省略可能です。これもよく呼ばれるメソッドなため、パフォーマンスを低下させるpropsやstateを更新する処理は最低限にしましょう。
##Unmounting
他のコンポーネントに切り替える前に現在のコンポーネントを破棄するための期間。1日に例えると日が暮れた後。
使用できるメソッド:

- componentWillUnmount()

現在のコンポーネントを破棄する直前に呼ばれるメソッドで、アニメーションやタイマーを設定していた場合はここで破棄します。そうしないと新しいコンポーネントのサイクルが始まった後も、その分のメモリが開放されないままになってしまいます。**ちなみにもうrenderが呼ばれることはないので、ここでpropsやstateを変更しても意味がありません。**

詳しくは[こちら](https://qiita.com/Julia0709/items/3c3fc8d29fd2e56ed7a9)の記事を参照してください。
# React hooks

- React **16.8** で追加された新機能です。
- stateやライフサイクルなどのReactの機能を、クラスを書かずに使えるようになります。つまり関数型もコンポーネントでも状態(state)を持つことができます。

## 関数型コンポーネントのstateの使い方
まずインポートします。

```jsx
import React, { useState } from 'react';
```
そしてstateの書き方

```jsx
const [プロパティ名, stateを変更するメソッド名] = useState(初期値);
```
では次にボタンをクリックするたびにカウントアップするプログラムをhooksを使わない書き方と使う書き方を比較します。
まず、最初に使わない書き方

```jsx:App.jsx
import React from 'react';

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

  setCount() {
    this.setState({count: this.state.count + 1})
  }
  
  render() {
      return (
        <div>
          <h1>{this.state.count}</h1>
          <button onClick={() => {this.setCount()}}>+</button>
        </div>
      )
  }    
}

export default App;
```
次にhooksを用いた書き方です。

```jsx:App.jsx
import React, { useState } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

    return (
      <div>
        <h1>{count}</h1>
        <button onClick={() => {setCount(count + 1)}}>+</button>
      </div>
    )
}

export default App;
```

## hooksを用いたライフサイクル

``useEffect()``を使います。

### useEffect
ReactのHooksの１つです。
公式では、副作用を実行するフックのように説明されています。
ざっくり言うと、ライフサイクルメソッドを関数コンポーネントで実現する為に使われたりします。

#### 使い方
まずはインポート。

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

**第二引数を空にすると、Render毎に実行される関数を取ります。**

```jsx
useEffect(() => {

  
});
```
**さらに第二引数に配列を渡すことができ、例えば空配列[]を記述すると``マウント・アンマウント時``のみ第１引数の関数を実行します。**

```jsx
useEffect(() => {

  
}, []);
```
**さらに第二引数の配列にstateのプロパティ名を渡せばその、``stateのプロパティ名が変更された時と最初のマウント時``に関数を実行されるようになります。**

```jsx
useEffect(() => {

  
}, [プロパティ名]);
```

このようにhooksを使用すると書き方がシンプルになり、バグなどを減らすことにも繋がります。
出来る限りこちらのhooksを用いた書き方をしましょう。

### useCallback←2020/06/13 追記
親で宣言したメソッドを子で実行するときに使います。(って覚えとくw)

```jsx:App.jsx
import React, { useState, useCallback } from 'react';
import Child from './conpoments/Child';

const App = () => {
  const [isMorning,setIsMorning] = useState(true);

  const handleClick = useCallback(() => {
    setIsMorning(!isMorning);
  }, [isMorning]);

    return (
      <>
        <Child isMorning={isMorning} handleClick={() => handleClick}/>
      </>
    )
}

export default App;
```

```jsx:Child.jsx
import React from 'react';

const Child =　(props) => {
    console.log(props.handleClick);
    return (
        <>
        {(() => {
          if (props.isMorning) {
            return <span>Good Morning</span>
          } else {
            return <span>Good Evening</span>
          }
        })()}
        <button onClick={props.handleClick()}>ボタン</button>
        </>
    )
}

export default Child
```
上の例のように親で``handleClick()``を宣言し、子の方で実行するときに**useCallback()**を使います。

因みに子にメソッドを送るときは``handleClick={() => handleClick}``のように``メソッド名={() => メソッド名}``とし、
子で``{props.handleClick()}``のように``{props.メソッド名}``で親で宣言したメソッドを実行できます。
今回は以上です。


# 最後に
もし、間違い等、アドバイス、ご指摘等有れば教えていただけたら幸いです。
次回はReact Routerについてなどをやっていきます。

長くなりましたが、最後まで読んでいただきありがとうございました。
[Twitter](https://twitter.com/watataku9)やってます。良ければチェックして見てください。:point_up::point_up::point_up: