Reactのメインコンセプト要点まとめ(1)

# この記事の位置づけ
React公式ドキュメントの「メインコンセプト」について、実際にReactの開発を行う中で特に参考になった章を要点の解説付きで纏めたものである。実際にReact公式ドキュメントを読み解いてもらうのが一番だが、時間がない人に要点だけでも読んでもらえるようにしたいと思い、纏めている。

公式のメインコンセプトでは、以下の章立てで説明をしている。
1. Hello World
2. JSXの導入
3. 要素のレンダー
4. コンポーネントとprops
5. stateとライフサイクル
6. イベント処理
7. 条件付きレンダー
8. リストとkey
9. フォーム
10. stateのリフトアップ
11. コンポジションvs継承
12. Reactの流儀

当記事では、以下の3章分について要点まとめをしている。
1. Hello World
2. JSXの導入
3. 要素のレンダー

# 出典元資料
React公式ドキュメントの[メインコンセプト](https://ja.reactjs.org/docs/hello-world.html)

# メインコンセプト
## 1. Hello World
### 一言コメント
まずは実践的なチュートリアルを使って、手を動かしてReactの動作を学習するのが望ましい。
まだチュートリアルをやっていない場合は、[React公式チュートリアル](https://ja.reactjs.org/tutorial/tutorial.html)を実際に作ってみて、感触を掴むことをお勧めする。

また、Reactは最新のJavaScript標準であるEcmaScript6でコードを記述することになる。
これまでJavaScriptでコードを書いたことがなかったり、最近のClassやアロー演算子といった書き方にまだ触れたことがない人は、まずはEcmaScript6基準のJavaScriptについて学習することをお勧めする。

## 2. JSXの導入
### 知っておくべきポイント
#### JSXを使う理由
UIがどのような見た目なのかを記述するために、ReactとともにJSXを使用することを公式は推奨している。
ReactでJSXを使うことは必須ではないが、JSXがあるためにReactは有用なエラーや警告をより多く表示できる。

```jsx:hello.js
const element = <h1>Hello, world!</h1>;
```

#### JSXに式を埋め込む
以下のように中括弧を使用することで、JSX内に式を埋め込むことができる。

```jsx:name.js
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
```

#### JSXで子要素を指定する
以下のように、JSX内で子要素を指定することで複数の要素を含め入れることも可能。

```jsx:hello.js
const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);
```

また、上記の書き方だとDIVタグが無駄に増えるという問題があるので、以下のような書き方もサポートされている。

```jsx:hello.js
const element = (
  <>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </>
);
```

### 一言コメント
最初はキモいが、慣れるとJSXでUIを構築するのが当たり前になる。便利。

## 3. 要素のレンダー
### 知っておくべきポイント
#### Reactの「要素」とは何のことなのか
> 要素とはReactアプリケーションの最小単位の構成ブロックです。

ふむ。。。
もう少し噛み砕くと、以下のようにReactのUIを定義したオブジェクトはReact要素であると言える。

```jsx:hello.js
const element = <h1>Hello, world</h1>;
```

公式でも「要素とコンポーネントを混同する人がいる」と指摘されているが、Reactの「要素」と「コンポーネント」は別の意味を持つ言葉である。公式では「要素とはコンポーネントを構成するもの」とされている。（要素はコンポーネントに内包されているUI定義）

#### ReactDOM.render() と React.Component.render() の違いは何なのか？
[ReactDOM（公式ドキュメント）](https://ja.reactjs.org/docs/react-dom.html)
[React.Component（公式ドキュメント）](https://ja.reactjs.org/docs/react-component.html)

違いとしては、、、

* `ReactDOM.render(element, container)`は、containerとして渡されたDOMに、React要素を実際にレンダリングしている
* `React.Component.render()`は、`React.Component`の`this.props`と`this.state`を調べた上でReact要素を返す（DOMノードのレンダリングはこの時点では行っていない）

ざっくりまとめると、以下のような使い分けになると思っている。

* コンポーネント単位（UIの部品単位）のReact要素を定義するのは`React.Component.render()`で行う
* HTMLのどのDOM要素にReactを描画するか指定するのは`ReactDOM.render()`を使用する
  * Create React Appで例えば、index.htmlの`<div id="root"></div>`にReact要素を描画している
  * 上記で指定したDOM要素にReact要素（Appコンポーネント）を描画するために、index.jsでは`ReactDOM.render(<App />, document.getElementById("root"))`と記述している

```html:index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <!--
      省略
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      省略
    -->
  </body>
</html>
```

```index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));
```

#### レンダリングされたReact要素の更新
React要素は[イミュータブル](https://qiita.com/s_harada/items/71a14ec07786682ec7e6#%E3%82%A4%E3%83%9F%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%81%A8%E3%81%AF)であり、一度React要素を作成すると変更することはできない。
イミュータブルということは、「変更」はできないが「置き換え」は可能ということである。
よって、ReactでUIを更新する唯一の方法は、新しいReact要素を作成して`ReactDOM.render()`に渡してDOMを再描画することになる。

ただし、実際には大抵のReactアプリケーション（Create React App含め）では、`ReactDOM.render()`は一度しか呼び出さない。
それらのReactアプリケーションでは、`ReactDOM.render(element, container)`のelementで渡すことになるReact.Componentにおいて、`React.Component.render()`関数を使用してコンポーネント単位のUI部品を置き換えることになる。

### 一言コメント
チュートリアルをやっただけでは、`ReactDOM.render()`と`React.Component.render()`の違いはイメージがつきにくいかもしれない。
ただ、DOMツリーとReactの紐付けをしているのはReactDOMであり、ここはぜひ抑えておいたほうがよいと思う。