ここからはじめるReactの基礎の基礎

# はじめに

この記事はReactの実装をしたことがない人、JSというとjQueryくらいしかやったことがない人でも理解出来るような内容です。

Reactをはじめるというとチュートリアルからはじめるのが基本かと思いますが、チュートリアルよりミニマムにReactってどんなの？というものを実際に実装して感じようというのが目的です。

ただし、`npm`はインストール済みが前提なので`npm`の準備は各自お願いします。

この記事ではReactの概念よりも実装を重要視します。なぜReactが良いのか等は他記事に譲らせて頂きます。

[Reactを使うとなぜjQueryが要らなくなるのか](http://qiita.com/naruto/items/fdb61bc743395f8d8faf)
[なぜ仮想DOMという概念が俺達の魂を震えさせるのか](http://qiita.com/mizchi/items/4d25bc26def1719d52e6)

簡単に説明すると、ReactはVirtual DOM (仮想DOM)という概念がキーポイントになり、それによって設計面、速度面に利点があります。特徴としてコンポーネントbaseのUIライブラリであることが挙げられて、実装する際にはこのコンポーネントについて理解することが重要です。

また、Fluxというアーキテクチャもありますが、今回はReactの基礎の基礎なので触れません。参考までにReduxがおすすめでチュートリアルも参考になりました。
[Redux Tutorial](http://redux.js.org/)

記法は`ES6`を採用しています。


# デモ

今回作成するのは以下のようなデモです。

![react3.gif](https://qiita-image-store.s3.amazonaws.com/0/40796/7f4177ac-9a7b-f956-f6d5-03d70b22b444.gif)

# 環境構築

まず環境構築を行います。[gaearon/react-hot-boilerplate](https://github.com/gaearon/react-hot-boilerplate) を使ってセットアップします。

```
$ git clone git@github.com:gaearon/react-hot-boilerplate.git
$ cd react-hot-boilerplate
$ npm install
$ npm start
```

ここで`http://localhost:3000/`にアクセスして 「Hello, world.」が表示されれば成功です。
これで準備は完了です。


さて、とりあえず表示は出来ました。ここからはその仕組みについて少し解説します。
この箇所ははじめはあまり理解できなくても問題はないのでよく分からなければさらっと読み飛ばしても構いません。

## webpack

このレポジトリでは`webpack`というビルドツールが使われています。

参考までにですが、以下の記事が分かりやすいと思います。
[webpack で始めるイマドキのフロントエンド開発](http://qiita.com/yosisa/items/61cfd3ede598e194813b)

すごくざっくりというと、`書いたJSファイル(Reactのコード）をひとつのファイルにいい感じにまとめて出力してくれる` やつです。

設定ファイルは `webpack.config.js` に書かれています。

## 仕組み

注目すべきファイルは以下の4つです。

- webpack.config.js
- index.html
- src/index.js
- src/App.js

まず、`src/index.js` は `src/App.js`を読み込んでいます。

読み込みは `import App from './App';`の部分です。

```js:src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

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

使うときは`webpack.config.js`の設定によって その`src/index.js` が `static/bundle.js` にコンパイルされます。

そのため表示されるファイルの `index.html` で、 `static/bundle.js`を読み込んでいます。

```html:index.html
<!doctype html>
<html>
  <head>
    <title>Sample App</title>
  </head>
  <body>
    <div id='root'>
    </div>
    <script src="/static/bundle.js"></script>
  </body>
</html>
```

さて、ここで再度 `src/index.js`を見てみます。

```js:src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

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

`ReactDOM.render(<App />, document.getElementById('root'));` の記述があると思いますが、これは`id='root'`の要素の中に`<App />`という要素を入れ込むという意味です。ここで`<App />`は `src/App.js`のことを指しています。

つまり、`src/App.js` に書いた記述がブラウザ上のページ(`index.html`)に反映される状態になっています。
ここで`src/App.js`を見てみると確かに `Hello, world.`の記述がありますね。

```js:src/App.js
import React, { Component } from 'react';

export default class App extends Component {
  render() {
    return (
      <h1>Hello, world.</h1>
    );
  }
}
```

以降の実装では、この`src/App.js`にコードを書いていくことで実装を行っていきます。

# 実装

実装のときにポイントとなるのは

- Component
- state
- props

の3点です。

以下の図を見ながら考えてみて下さい。

Twitterの画面を例にしてみます。ツイートのタイムラインがあります。それを親コンポーネントとすると、ひとつひとつのツイートのボックスが子コンポーネントにあたります。そのようにひとつひとつをコンポーネントに見立てていく感覚が大切です。

また、コンポーネントごとの変数を管理を`state`が、コンポーネント間の変数の受け渡しを`props`が担います。

![react-component.png](https://qiita-image-store.s3.amazonaws.com/0/40796/1ebf1875-855a-20dc-9537-4ca7c181729c.png)

それでは実際に実装していきます。


## state

最初はコンポーネントはひとつしかありません。それは`Hello World`を出力するコンポーネントです。
厳密ではないですが、ひとつひとつのクラスがコンポーネントになっているイメージです。
まず以下のように編集してみましょう。

```js:src/App.js
import React, { Component } from 'react';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'James'
    }
  }

  render() {
    const name = this.state.name;

    return (
      <h1>Hello, {name}.</h1>
    );
  }
}
```

コンポーネント内に変数を用意します。コンポーネント内部の変数は`state`でしたね。まずは初期値を用意しなければなりません。
そのために`constructor`を使います。`constructor`は初期化のための特殊なメソッドですので覚えてしまいましょう。`super(props)`の記述は`constructor`をオーバーライドするので書きますが、はじめは決まりごととして覚えて構いません。そして以下のような記述によって`state`を設定することが出来ます。

```js
  constructor(props) {
    super(props);
    this.state = {
      name: 'James'
    }
  }
```

実際にこれを表示しましょう。`this.state.name`のような記述で`state`にアクセス出来ます。また`{}`で囲むことで変数を表示することが出来ます。


```js
  render() {
    const name = this.state.name;

    return (
      <h1>Hello, {name}.</h1>
    );
```

![スクリーンショット 2016-10-02 11.30.06.png](https://qiita-image-store.s3.amazonaws.com/0/40796/dfe3d4e1-0420-44b4-8a89-5f2ad85a16c0.png)

これで反映されました。

## onChange

ここで`input`の入力欄をつくります。

```js:src/App.js
import React, { Component } from 'react';

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'James'
    }
  }

  render() {
    const name = this.state.name;

    return (
      <div>
        <h1>Hello, {name}.</h1>
        <input
          type="text"
          value={name}
          onChange={ e  => {
            this.setState({
              name: e.target.value
            })
          }}
        />
      </div>
    );
  }
}
```

以下のように`input`の入力欄を作成出来ます。ちなみに一見htmlですが`JSX`という記法になります。ほとんどhtmlライクに書けます。
さて注目は`onChange`ですがこれはイベントハンドラです。inputの変更を検知して処理が行われます。ここでは文字を変更させたら`{}`内の処理が実行します。`onClick`等他のものもあるので調べてみると良いかと思います。
また、`this.setState`によって`state`の値を変化させています。注意ですが、`this.state.name = 'hoge'`のように変更してはいけません。`this.setState`を使うことによって画面に変更が反映されます。

ちなみに`e.target.value`は`e`でeventを受けてinputに入力したvalue値を取っています。
また `=>` これはES6のアロー関数を採用しているものなので気になる方は調べて見て下さい。

```js
<input
  type="text"
  value={name}
  onChange={ e  => {
    this.setState({
      name: e.target.value
    })
  }}
/>
```

もう一点注意ですが、`<h1>`と`<input>`を`<div>`で囲っています。これは`return`の中のDOM要素はひとつにしないとエラーになるためです。


以下のように反映されているはずです。

![react2.gif](https://qiita-image-store.s3.amazonaws.com/0/40796/b74a6bd6-e88d-cca1-1c04-a18da4a2bb58.gif)


## props

機能自体はほぼ出来ましたが、名前表示の部分だけを子のコンポーネントに切り出してみます。
また、`state`の初期値を空にしておきます。

```js:src/App.js
import React, { Component } from 'react';

class Name extends Component {
  render () {
    const name = this.props.name;

    return (
      <span style={{color: 'red'}}>{name}</span>
    );
  }
}

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ''
    }
  }

  render() {
    const name = this.state.name;

    return (
      <div>
        <h1>Hello, <Name name={name} />.</h1>
        <input
          type="text"
          value={name}
          onChange={ e  => {
            this.setState({
              name: e.target.value
            })
          }}
        />
      </div>
    );
  }
}
```

子のコンポーネントを以下のように作成しました。ポイントは`props`です。親で指定した`props`(指定の仕方はこの後で）を`state`と同じ要領で呼び出します。これで`return`の中身を親コンポーネントで表示出来ます。

```js
class Name extends Component {
  render () {
    const name = this.props.name;

    return (
      <span style={{color: 'red'}}>{name}</span>
    );
  }
}
```

さて親コンポーネントで子コンポーネントの呼出ですが以下のような`<Name />`で呼び出せます。`<Name name={name} />`のようにプロパティを指定するとpropsとして子コンポーネントに値を引き渡せます。

```js
<h1>Hello, <Name name={name} />.</h1>
```

以上で以下のように反映されます。

![react3.gif](https://qiita-image-store.s3.amazonaws.com/0/40796/7f4177ac-9a7b-f956-f6d5-03d70b22b444.gif)

これで完成です！

# 終わりに

これだけ分かればReactの基礎の基礎は分かったことになると思います。以降チュートリアルをやるなどやってみましょう。

[React チュートリアル](https://facebook.github.io/react/docs/tutorial-ja-JP.html)

今回採用したES6でのチュートリアルも作成されていました。
[ES6版React.jsチュートリアル](http://qiita.com/nownabe/items/2d8b92d95186c3941de0)

また、僕のReact勉強のログとして以下のレポジトリにまとめてあります。（そのため、チュートリアルほぼそのままのやつもあったりです。今度アップデートさせたいと思っています。）
ローカルで起動させると教科書的に使えるかと思うので参考になれば幸いです。
今回の記事の内容の機能もこれの一番最初のデモです。
[kuboshizuma/react-practice](https://github.com/kuboshizuma/react-practice)