Reactの基礎を学ぶ

# 前提
可能な限りES6の記載で説明している（はず

# Reactって
+ View部のみ担当するライブラリ
+ 仮想DOMにより、余計なレンダリングが発生しない

# 環境
## 環境作成
公式見ると、create-react-app使いなさいって感じなので入れる。
https://github.com/facebookincubator/create-react-app

```bash:create-react-appインストール
npm install -g create-react-app
```
```bash:プロジェクト作成
create-react-app プロジェクト名
```

## ローカルサーバ起動
```bash
cd プロジェクト名
npm start
```

この状態で
http://localhost:3000/
を開くと、
Reactの初回画面が表示される。

## ファイル編集用のエディタ(Atom)
**①Atomインストール**
https://atom.io/

**②gitもいれたほうがいい**

**③日本語化**
「file」→「Setting」→「install」→「japanese-menu」インストール

**④入れると捗るパッケージ**
autocomplete-paths
convert-to-utf8

**⑤React用に捗るパッケージ**
react
Atom-beautify

# JSXを知ろう
## JSXって
Reactは、仮想のDOMを駆使して、望む結果を最終的に表示する。

その過程をHTMLっぽく記載できる方法がJSX。
※HTMLではないので注意

特徴としては、

+ HTML5のタグはすべてつかえる
+ カスタムコンポーネントをタグ名として使える
+ JavaScriptに比べて構造がわかりやすい

などがある。

## JSXのわかりやすさを知る
例えば、
「h1タグを用意したい」
とき

```js:素のJavaScript
React.DOM.h1({className: 'question'}, '質問');
```

```html:JSXなら！
<h1 className="question">質問</h1>
```
　
ちなみに上記をカスタムコンポーネントとして作成すれば

```html
<App>質問</App>
```

こんな記述もできるように。

## JSXとHTMLの違い
**①JSX独自の属性がある**
key、ref、dangeroslySetInnerHTML

**②使えない属性もある**
class、forは、JavaScriptでも使われるため、属性として使用できない。
以下のように置き換えて使うこと。

|HTMLの場合|JSXの場合|
|:--|:--|
|class|className|
|for|htmlFor|

## 属性値にオブジェクトを渡す
プロパティ名がキャメルケースのオブジェクトを属性値として
渡すことが可能。

```jsx
var styles = {
  borderStyle: "#999",
  borderThickness: "1px"
};

〜

/* JSX部 */
<div style={styles}>・・・</div>
/* JSX部 */
```

# コンポーネントを知ろう
## コンポーネント？
個人的なイメージで説明すると、

+ JSXで表現されたタグ
+ 親タグとその子孫タグ

がコンポーネント。

これも
`<div></div>`
これも
`<div><h1>title</h1></div>`
１コンポーネントとしての扱い。

## カスタムコンポーネント
状況に応じて表示を変える自作のタグ。
実態はJavaScriptのコード。

下記は広義でコンポーネント、狭義だとカスタムコンポーネント。
```<Custom></Custom>```

## コンポーネントでなにするの？
カスタムコンポーネント内のJSXで、
更に別のカスタムコンポーネントを表示。
そのカスタムコンポーネント内のJSXで、またカスタムコンポーネント・・・

といったことを繰り返して、Reactとしての画面描画を行う。

## コンポーネント例
create-react-appで作成したプロジェクトを
もうちょっと簡易にした例を参考に、流れを把握しよう。

関係者

|./||
|:--|:--|
|public/|index.html|
|src/|index.js|
||App.js|

```jsx:コンポーネント作成例(App.js)
//必須
import React, { Component } from 'react';

//Appクラス = Appコンポーネント(カスタムタグ)
class App extends Component {
  render() {
    return (
      //returnの中にJSXを記載
      <div className="driver">
        <h2>質問</h2>
      </div>
    );
  }
}

//他の場所で読み込んで使えるようにexport
export default App;
```

```jsx:コンポーネント呼び出し例(index.js)
//必須
import React from 'react';
import ReactDOM from 'react-dom';

//コンポーネント読み込み
import App from './App';

//(id="root"のところに)描画
ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```

```html:index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>React App</title>
  </head>
  <body>
    /* ↓この中に描画される */
    <div id="root"></div>
  </body>
</html>
```

## 動的な値を埋め込める
波括弧で変数をJSXの中に埋め込んだりできる。

```jsx:App.js
class App extends Component {
  render() {
    var text = '質問';

    return (
      <div className="driver">
        <h2>{text}</h2>
      </div>
    );
  }
}
```

## 子ノードの受け取り方
```html
<App>質問</App>
```
こんなJSXがあったとして、
Appコンポーネントでは、その子ノード(ここでは質問というテキスト)を
「this.props.children」で受け取ることができる。

# コンポーネントを使いこなすための追加知識
## props
コンポーネントのプロパティのこと。

コンポーネントが自己を表現する時に使えるものといえば
プロパティしか無いですよね。

カスタムコンポーネントは
プロパティをpropsというオブジェクトで参照できるようにして、
その状態を見て、自身の描画を変える。

### propsを設定
```jsx
var hoge = [{text: '質問' }];

~

/* JSX */
<List value={hoge} />
/* JSX */
```

関数も渡せる。

### propsの参照
this.props
で行う。

### propsの変更や更新
禁止禁止！

親コンポーネントから受け取ったものを変更するなんて、
過去改変して自己の存在を変えるようなものだぞ・・！

### propsのデフォルト値
defaultProps(prototypeプロパティ)で設定する。

```jsx
class App extends Component {
  render() {
    //propsの参照
    var text = this.props.text;

    return (
      <div className="driver">
        <h2>{text}</h2>
      </div>
    );
  }
}

//prototypeプロパティで設定
App.defaultProps = {text: '質問'};
```

### propsのバリデーション
ES6では、propTypes(prototypeプロパティ)で、
ES6以前は、propTypes(クラス内関数)で、
コンフィグオブジェクトを指定する。

```js
App.propTypes = { num: React.PropTypes.number };
```

※随時追加

|オブジェクト|説明|
|:--|:--|
|||

## state
コンポーネントの状態を保持するオブジェクト。

stateを子コンポーネントのpropsとして渡せば、
親コンポーネントの今を、子コンポーネントに伝搬させることになるので、
結果として、画面の(再)描画が行える。

```
----------------       --------------------------------
|俺今、こんな状況 |　　　 |じゃあ俺コレ使って、自分の表示するわ |
-  -------------       ----- --------------------------
 V                         V

(親)つ  (state | props)  ⊂(子) 
```

### stateの初期化
ES6では、constructor(クラス内関数、後述)で、
ES6以前は、getInitialStateで行う。

```js
constructor(props) {
    //必須
    super(props);

    //初期化
    this.state = {title: 'list'};
}
```

### stateの参照

``` this.state ```

### stateの変更
```this.setState({key: value})```
で行う。

状態の変更が発生するので、再描画(render関数)が行われる。
setStateで変更しないと、画面に反映されないということでもあるので、
直接stateをいじるなんてことはしないこと。

## イベントハンドラ
コンポーネントに、イベントハンドラを指定できるが、
少しだけ特殊な仕様がある。

### 記載の流れ
```jsx
class App extends Component {
  //①イベントハンドラ用関数を定義
  eClick(event) {
    //処理
  }
  render() {
    return (
      <div className="driver">
        /* ②イベント紐付け */
        <input type="button" onClick={this.eClick.bind(this)} value="1" />
      </div>
    );
  }
}
```

### eventについて
イベントハンドラ内で、その発火元の情報を受け取りたい場合、
eventを第1引数でうけとると、そこから抽出が可能。
```console.log(event.target.value); //1```

### bind(this)
ES6以降で、イベントハンドラ内でthis(コンポーネント)を使いたい場合、
constructorかJSX内でthisをbindしないといけない。

```html
<input type="button" onClick={this.eClick.bind(this)} value="1" />
```

```js
constructor(props) {
  super(props);

  this.eClick = this.eClick.bind(this);
}
```

# コンポーネントのライフサイクル
コンポーネントからコンポーネントを呼ぶような作りになってくると、
コンポーネント内のライフサイクルも重要になってくる。

ライフサイクルは、
コンポーネント内で規定の関数、prototypeプロパティで実装してあげると、
所定のタイミングで呼ばれる。

**描画まで**

|動作タイミング|呼ばれる関数等|主な使用目的|
|:--|:--|:--|
|初回描画時のみ<br>初期処理前|defaultProps|propsのデフォ値設定。<br>ES6の場合、prototypeプロパティによる定義で実装。<br><br>※ES6以前の場合、getDefaultProps。|
|初期処理|constructor(props)|stateの初期化。<br>```super(props);```を記載しなければならない。<br>このタイミングでthis.propsが使えるようになる。<br><br>※ES6以前の場合、getInitialState。|
|描画直前|componentWillMount||
||render()|省略不可。仮想Domの作成。|
|描画後|componentDidMount|DOMの操作。|

**描画中**

|動作タイミング|呼ばれる関数等|主な使用目的|
|:--|:--|:--|
|props変更時|componentWillRecieveProps|stateの変更など。|
|props、state変更時|shouldComponentUpdate|falseを返すことで、以降の処理をスキップできる。|
|描画直前|componentWillUpdate||
||render()||
|描画後|componentDidUpdate|DOMの操作。|

**コンポーネント破棄**

|動作タイミング|呼ばれる関数等|主な使用目的|
|:--|:--|:--|
||componentWillUnmount||

図示している方がいらっしゃるのでこれがわかりやすいかも。
[React component ライフサイクル図](http://qiita.com/kawachi/items/092bfc281f88e3a6e456)