【React】公式ドキュメントの私的まとめ

Reactがマジでわかんない
おそらく買った本がむずすぎた
[公式](https://ja.reactjs.org/docs/introducing-jsx.html)を読んで見ることにした
その私的まとめ

#JSXの導入

```javascript
const element = <h1>Hello, world!</h1>;
```
javascriptの拡張言語
使う理由はjavascriptにHTMLを書くようにかけるので直感的にわかりやすい

##式の書き方
`{}`の中に式を書けばいい
JSXは式だだから`if`にも`for`にも打ち込める

#render
```html
<div id="root"></div>
```
上記がHTMLファイルにあるとするとこれルートDOMを言うことにする

React要素をルートDOMにレンダリング(HTMLを人が見れる形にする)するには
React.render()に渡す

```javascript
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
```

|引数|意味|
|---|---|
|第1|React要素|
|第2|ルートDOM|

**Reactは意味ミュータブル**
更新するには新しい要素を作成してReact.render()に渡す
以下の公式のコードには感動した
これは秒刻みで動く時計の例

```javascript

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);
```
もう一度いうと更新するには
新しく要素を作詞→React.render()に渡す、という流れ

##React は必要な箇所のみを更新する
これを見たとき楽しくなった。とある本を読んで勉強するよりドキュメント読んだほうが遥かに楽しいし勉強になる。
今後は「入門」という文字の入った本に気をつけよう

話を戻すと先の時計だが、ディベロッパツールで見てみると時刻のとこだけのDOMを変更している

これはとある入門書を見て知っていたが百聞は一見にしかずとはまさにこのこと
理解ができた感動した
#componentとprops
コンポーネントで部品を独立したものにして再利用可能にできる

コンポーネントはjavascript関数に似ていてpropsという入力を受け取りReactエレメントを返す
**コンポーネントはReactエレメントを返す。**
**コンポーネントはReactエレメントを返す。**
**コンポーネントはReactエレメントを返す。**

そうだったのか。。
コンポーネントはReactエレメントを返すのか。。

コンポーネントの定義には関数とクラスがある、これは知ってる

```javascript

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

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);
```

上記コードの説明も丁寧でわかりやすかった

このときコンポーネント名は大文字で始める

```javascript
import React from 'react';
import ReactDOM from 'react-dom';

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

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```
このコードを見たとき更新かなと思ったが、3行表示された、ああそうだったと、忘れてるなぁと思った
##コンポーネント抽出

```javascript
unction Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}
```
上記コードがコードの分割により以下のようになる

```javascript
function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />
  );
}

function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}
```
見やすい、スッキリ
###Avatarコンポーネントの作成
このコンポーネントは自身がレンダリングされることを想定していない
propsの名前がuserがるかわれているのは
**これはコンポーネント自身の観点で名前をつけることが推奨されているから**

長いコードを関数化する作業に似ている

##propsは読み取り専用
propsは変更してはいけない
Reactコンポーネントはpropsに対して純粋関数であること

#stateとライフサイクル
先の秒刻み時計で進めていく
以下からはClockコンポーネントを再利用可能かつカプセル化されたのにする方法

```javascript
function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);
```
まずは見た目のカプセル化

しかし理想は以下のコードだけを書いてClock自身を更新させたいらしい

```javascript
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
```

これの実現には`state`を追加する必要があるという
このstateはコンポーネントによって完全プライベートなもの

##関数をクラスに変換
以下の手順でクラスに変換

1. React.Componentを継承
2. render()というからメソッドを用意
3. 関数の中身をそのメソッドの中に書く
4. render()内のpropsをthis.propsへ書き換える


```javascript
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
```
renderメソッドは更新が発生したときに毎回呼ばれるが同一DOMノード内で`<Clock />`をレンダーしている限り、Clockクラスのインスタンスは1つだけ使われる

つまり同一DOM無いであればいくらrenderメソッド内のClockを呼び出しても同じインスタンスが使われる、保持したものはそのまま使えるということ、かな
##クラスにローカルなstateを追加
以下の3ステップでdateをpropsからstateに移す

1. render()メソッド内の`this.props.date`を`this.state.date`に書き換える
2. this.stateの初期状態を設定するクラスコンストラクタを設定
3. `<Clock />`要素からdateプロパティを削除

`2`では親のコンストラクタへのpropsの渡し方に注意
クラスコンポーネントでは常にpropsを引数として親クラスのコンストラクタを呼び出す必要がある

```javascript
super(props)
```
とある入門書ではなぜこれを書くのか。
初見でこれを見たときなんで親クラスのを呼び出しているのかわからなかった。
今もなぜだかわからないけどそうおいうものだとわかっただけもスッキリする。

##クラスにライフサイクルメソッドを追加
コンポーネント破棄時にリソースを開放したほうがいい

タイマー設定は最初にClockが描画(マウント)されるとき。
タイマークリアはClockが生成したDOMが削除(アンマウント)されるとき

このようなライフサイクルメソ度を使っていく
###componentDidMount
コンポーネントがマウントされた直後に呼ばれる

```javascript
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
```
タイマーIDをthis上に格納しているのには訳がある


###componentWillUnmount
コンポーネントがアンマウントされた直後によばれる
このタイミングでクリアするのがいい

```javascript
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
```

最後にtick()を作る
コンポーネントがローカルstateの更新をするためにthis.setStateを使う

```javascript
  tick() {
    this.setState({
      date: new Date()
    });
  }
```

###何が起きたかの振り返り
1. `<Clock />`がReactDOM.render()に渡されると.ReactはClockコンポ-ネントのコンストラクタを呼び出す。このときにstateを初期化。
2. 次にReactはrender()を呼び出す。
3. Clockの出力されるとReactはcomponentDidMountを呼び出す。
4. tick()が実行されるとsetStateでstateが変更される。それをReactが感知してrender()を再度呼び出す。そしてthis.state.dataが前回と違っていいるためReactはDOMを更新
5. Clockコンポーネントが削除されたらcomponentWillUnmountでタイマーが止まる

##stateを正しく使用する
###stateを直接変更しない
以下は再レンダーされない

```javascript
this.state.comment = 'Hello';
```
setStateを使えばいい

```javascript
this.setState({comment: 'Hello'});
```
直接書き換えた場合、再レンダリングされない
Reactが変更を検知できないため。