【Part2】はじめてのReact勉強メモ

# はじめに

[前回](https://qiita.com/Grebinskij/items/82c3a6b3def452d76633)の続きです。

公式チュートリアルの[Hello World](https://reactjs.org/docs/hello-world.html)からやってみます。

# やってみる

## Hello World

前回構築した環境の`index.js`を改変して、以下のようにしてみます。
`ReactDOM.render()`で既存のDOMに`ReactDOM`をバインドする感じですね。

```JavaScript
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

// ここを追加
ReactDOM.render(
  <h1>Hello World!</h1>,
  document.getElementById('root')
);

// ここを一旦コメントアウト
// ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
```

## Introducing JSX

先ほど`ReactDOM.render()`で使った表現、変数にも代入できるんですね。

```JavaScript
const element = <h1>Hello, world!</h1>;
```

`JSX`内に変数を埋め込むにはこんな感じでやるみたいです。

```JavaScript
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);
```

関数も使えるんですね。

```JavaScript
const formatName = ...

const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);
```

タグの属性に文字列を指定する場合はこんな感じにして、

```JavaScript
const element = <div tabIndex="0"></div>;
```

変数を埋め込むときはこんな感じだそう。

```JavaScript
const element = <img src={user.avatarUrl}></img>;
```

空のタグはこんな感じで閉じて、

```JavaScript
const element = <img src={user.avatarUrl} />;
```

もちろんタグのネストもできるよ。

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

`XSS`なんかの対策で、JSXは描画前に内部の値をすべて文字列にエスケープするようになっているので、アプリに書かれていないものを直接差し込むのは出来ないようになっているそう。

```JavaScript
const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;
```

ここまで見てきた`JSX`、実際はどんな形になっているの？って話なんですが、こんな感じに書いた場合

```JavaScript
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
```

実際は`Babel`が以下のようにコンパイルしてくれていて、

```JavaScript
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);
```

`React.createElement`内で幾つかチェックをかました後にこんな感じの値が返ってくるようになっているそう。

```JavaScript
// Note: this structure is simplified
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};
```

### index.js

この章で出てきた要素をいろいろと`index.js`に混ぜてみました。

```JavaScript
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

const name = 'world';
const formatName = name => `Hello ${name}.`;
const hash = {
  a: '#a',
  b: '#b'
}

// ここを追加
ReactDOM.render(
  <div>
    <h1>This is title.</h1>
    <h2>{formatName(name)}</h2>
    <h2>
      <a href={hash.a}>Jump to #a</a>
      <a href={hash.b}>Jump to #b</a>
    </h2>
  </div>,
  document.getElementById('root')
);

// ここを一旦コメントアウト
// ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
```

## Rendering Elements

`DOM`と`ReactDOM`は違うよという導入です。

```html
<div id="root"></div>
```

これを"root"DOMと呼んで、この内部をreactの支配下にするという話ですね。要は仮想DOMでやるという話だと思います。
一からreactアプリを作る際は基本的にこの"root"DOMはひとつですが、複数持っても良いそうです。

Reactエレメントは一度描画されれば基本的に不変なので、以下のように再描画する必要があるそうです。

```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);
```

さっそく`index.js`に混ぜてみました。

```JavaScript
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

const name = 'world';
const formatName = name => `Hello ${name}.`;
const hash = {
  a: '#a',
  b: '#b'
}

// ここを追加
const tick = () => {
  ReactDOM.render(
    <div>
      <h1>This is title.</h1>
      <h2>{formatName(name)}</h2>
      <h2>
        <a href={hash.a}>Jump to #a</a>
        <a href={hash.b}>Jump to #b</a>
      </h2>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>,
    document.getElementById('root')
  );
}

setInterval(tick, 1000)

// ここを一旦コメントアウト
// ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
```

# 終わりに

本日はここまで。記法こそ`Vue.js`とは違いますが、結構すんなりと受け入れながら理解できています。
次回はComponents and Propsからやっていきます。