はじめてのReact(+環境構築)

#Reactとは
・UIを構築するためのJSライブラリ
・HTMLを直接は使わずJavaScriptで動的にUI生成する仕組み
・JavaScriptのエコシステム(テストツールなど)が使える
・コンポーネント指向で、独立した部品を組み合わせて作る
・Virtual DOMを用いた画面の差分描画を行い高速な画面表示を実現する

###①コンポーネントとは
・UIの構成要素
・Reactでは、コンポーネントを組み合わせてUIを作る
・コンポーネントには表示系のだけでなく処理も記述する

###②ステート
・コンポーネントの内部の変数のようなもの
・コンポーネントが生成される際に初期化され、その後はコンポーネントの状態の変化を保持するために使われる。
・コンポーネントの外部からはアクセスできない。
・ステートに頼らず、使わないで済むなら使わない方が良い

###③プロパティ
・コンポーネントに外部から与えられるオプションのようなもの。
・HTMLで言う属性のようなもの。
・コンポーネントの内部では、プロパティはステートと同じように変数としてアクセスできる。
・コンポーネントはプロパティの値を変更してはいけない。
・プロパティは外の世界から一方的に伝えられるもので、それを使って外に何かを発信することはできない。

###④JSX
・JavaScriptの中でXMLの文法によってReactコンポーネントを配置できるようにした言語。
・XMLライクのシンタックスを追加する言語拡張。
・JSXを使うとJavaScriptの中にHTMLのタグを埋め込むように記述することができる

###⑤Virtual DOM
・
・Reactが内部で使っている仕組み
・JavaScriptで生成したDOMを模倣したデータ構造で差分計算をして、実際のDOMに反映させるため、処理が高速になる


```js
const element = <h1 className="hello">これはJSXです</h1>;
```

```js
const App = () => (
  <div>Hello React!</div>
);

const render = () => ReactDOM.render(<App />, document.getElementById('app'));
render();
//・「App」App内で定義されている<div>はHTMLの記法と似ています。これはJSXと言ってXMLであり正確にはJavaScriptに変換されるもの。
//・「render」Reactコンポーネントをブラウザに描画するためのもの
```


####Reactのコンポーネントは再利用可能なパーツ

```js
//コンポーネント定義
const Hello = () => (
  <div>Hello</div>
);
//コンポーネントを使う
const App = () => (
  <div>
    <Hello />
  </div>
);
```
・コンポーネントはHTMLのタグと区別するためコンポーネントは大文字で始まる名前にする。
・XMLはHTMLと違い必ず閉じタグが必要。 <Hello />は<Hello></Hello>の省略記法
・コンポーネントの定義は 使う位置より上に書くようにする

####コンポーネントにスタイルをつける
・HTMLでCSSを使ってスタイルをつけるように、コンポーネントでも同じことができる。
・ReactではInline stylesという方法でスタイルをつける。

```js
const Hello = () => (
  <div style={{ color: 'red'}}>Hello</div>
);
```
・外側はReact、内側はJS

```js
const myStyle = {
  color: 'red',
  marginLeft: 100,
};
```
・CSSと違いキャメルケースで


##props
・コンポーネントを作る目的は再利用
・再利用が有効に働くようにするにはパラメータを受け取るようにできることが重要
・Reactではコンポーネントが受け取るパラメータオブジェクトをpropsと言う
・propsは通常のJavaScriptオブジェクト

```js
//propsを受け取る
const Hello = ({ name }) => (
  //ここの{name}はJSで、{name + '!'}ともかける
  //JSX内の{}には任意のJavaScript表現を書くことができる
  <div>Hello {name}</div>
);
//propsを渡す
const App = () => (
  <div>
    //name="World"の部分はname={"Mina" + 3}などとしてJavaScript表現を書くことも可能
    <Hello name="World" />
  </div>
);
```

####コンポーネントを再利用する


```js
const Hello = ({ name, color }) => (
  <div>
    //style={}の中の{ color }は{ color: color }の意味
    <p style={{ color }}>Hello {name}!</p>
  </div>
);

const App = () => (
  <div>
    <Hello name="World" color="blue" />
    <Hello name="Ebisu" color="red" />
  </div>
);
```

####配列から展開する
・データなどの配列からコンポーネントを展開することができるとより再利用性の価値が生まれる。

```js
//再利用するコンポーネント
const Hello = ({ name, color }) => (
  <div>
    <p style={{ color }}>Hello {name}!</p>
  </div>
);

//データの展開を利用しない場合
const App = () => (
  <div>
    <Hello name={items[0].name} color={items[0].color} />
    <Hello name={items[1].name} color={items[1].color} />
    <Hello name={items[2].name} color={items[2].color} />
    <Hello name={items[3].name} color={items[3].color} />
  </div>
);
//データの展開を利用する場合
const App = () => (
  <div>
    {items.map((item) => (
      <Hello name={item.name} color={item.color} />
    ))}
  </div>
);
```

####フォームを利用する

```js
//ボタンを表示する
const MyButton = () => (
  <div>
    <button onClick={() => alert('clicked')}>Click Me</button>
  </div>
);   
//テキストボックスを制御する
let textData = '';
const setTextData = (event) => {
  textData = event.target.value;
  //10文字より多く入力できないよう
  if (textData.length > 10) {
    textData = textData.slice(0, 10);
  }
  //render()をtextデータが更新されるたびに呼び出す
  render();
};
//テキストボックスを定義する
const MyBox = () => (
  <div>
    <input type="text" value={textData} onChange={setTextData} />
  </div>
);

const App = () => (
  <div>
    <MyBox />
  </div>
);

const render = () => ReactDOM.render(<App />, document.getElementById('app'));
```
・Reactの魅力の一つとして、フォームの値の制御が柔軟にできるということ。
いわゆるフォームのバリデーションが、任意のコードで書くことができる


####フォームの使用

```js
const items = [
  { name: 'aaa', color: 'black' },
  { name: 'bbb', color: 'green' },
  { name: 'ccc', color: 'pink' },
  { name: 'ddd', color: 'yellow' },
];
//データを入力した際の処理
let nameData = '';
const setNameData = (event) => {
  nameData = event.target.value;
  render();
};
//データ追加ボタンをタップした際の処理
const addData = () => {
  items.push({ name: nameData, color: 'black' });
  nameData = '';
  render(); 
};
//登録フォームの定義
const MyForm = () => (
  <div>
    <input type="text" value={nameData} onChange={setNameData} />
    <button onClick={addData}>Add Data</button>
  </div>
);
//表示、削除フォームの定義
const Hello2 = ({ name, color, onDelete }) => (
  <div>
    <p>
      <span style={{ color }}>Hello {name}!</span>
      <button onClick={() => onDelete()}>Delete</button>
    </p>
  </div>
);
//削除処理
const deleteItem = (index) => {
  items.splice(index, 1);
  render();
};
const App = () => (
  <div>
    <MyForm />
    {items.map((item, index) => (
      <Hello2 name={item.name} color={item.color} onDelete={() => deleteItem(index)} />
    ))}
  </div>
);

const render = () => ReactDOM.render(<App />, document.getElementById('app'));
render();
```







##ES2015(ES6)
・ReactでコーデイングするにはES2015が便利。
・ES2015はトランスパイルが必要だけれど、JSXを利用するとトランスパイルするため敷居が下がる。
####ES2015について
#####「const」と「let」
・ES2015ではvarは基本的に使わず、代わりにconstとletを使うことが推奨され
・constは再代入しない変数の宣言に用います。
・letは再代入が必要な変数の宣言に用います。
・再代入とimmutabilityは別物ですので注意が必要です。

```js
const x = 1;
let y = 2;
y = 3;
```

#####object shorthand
・ES2015ではオブジェクトのプロパティ名と値の変数名が同じ場合、省略記法を使うことができます。

```js
const foo = 'abc';
const bar = { foo }; // same as { foo: foo }
```

#####destructuring object
・destructuring assignmentという簡便な記法
・変数への代入だけでなく、関数のパラメータ宣言でも用います。

```js
const obj = { first: 'Ebisu', last: 'JS' };
const { first, last } = obj;
// first === 'Ebisu', last === 'JS'

function printName({ first, last }) { console.log(first, last); }
printName(obj);

// same as
// function printName(name) { console.log(name.first, name.last); }
```

#####アロー関数
・() => ...という記法

```js
const f1 = function(x) { console.log(x); };
const f2 = (x) => { console.log(x); };
// f1 and f2 is almost the same

const f3 = (x) => { return (x + 1); };
const f4 = (x) => (x + 1);
// f3 and f4 is the same

const f5 = x => x + 1;
```


##その他
###1.  コンポーネントの書き方

(1)ドキュメントに記載されている基本的な書き方

```js:createClass
var Hello = React.createClass({
  render: function() {
     return (
       <div>Hello {this.props.name}</div>
     );
  }
})
```

(2)ES2015からの書き方

```js:extendsComponent
class Hello extends React.Component {
  render() {
    return (
      <div>Hello {this.props.name}</div>
    );
  }
}
```

(3)React v0.14から可能になったfunction components

```function
function Hello(props) {
  return (
    <div>Hello {props.name}</div>
  );
}
```

(4)ES2015の場合はアロー関数でも書ける

```js:ArrowFunction
const Hello = (props) => (
  <div>Hello {props.name}</div>
);
```

```js:returnが必要な場合
const Hello = (props) => {
  // ここに何かしらの処理が入る場合
  return (
    <div>Hello {props.name}</div>
  );
};
```

(5)ES2015ではpropsを引数宣言で展開することができる

```js:restructuring
const Hello = ({ name }) => (
  <div>Hello {name}</div>
);
```

```js:function宣言でも可能
function Hello({ name }) {
  return (
    <div>Hello {name}</div>
  );
}
```

###2. コンポーネントのstate
・コンポーネントにはprops以外にもstateと言う状態を持つ手段がある。

```js:stateを使う場合
class Hello extends React.Component {
  constructor() {
    this.state = { count: 1 };
    this.incrementCount = this.incrementCount.bind(this);
  }
  incrementCount() {
    this.setState({ count: this.count + 1 });
  }
  render() {
    return (
      <div>
        Hello {this.props.name}
        <button onClick={this.incrementCount}>
          count={this.state.count}
        </button>
      </div>
    );
  }
}
```

#####react-compose-state
・個人プロジェクトなどの手軽なコーディングではsingle storeはオーバスペックである場合もあります。そのような場合でコンポーネントレベルのstateを使いつつ、上記のようなclassを使わない方法としてreact-compose-stateがあります。

```js
const Hello = composeWithState({ count: 1 })(({ name, count, setCount }) => (
  <div>
    Hello {name}
    <button onClick={() => setCount(count + 1)}>
      count={count}
    </button>
  </div>
);
```

###3. コンポーネントのライフサイクルメソッド
・コンポーネントにはライフサイクルメソッドというものがある。
・コンポーネントが初めて使われた時にDOMレンダリング後に呼ばれるもの。

```js:componentDidMount
class Hello extends React.Component {
  componentDidMount() {
    console.log('Hello component is initialized.');
  }
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}
```

###4. PropTypes
・PropTypes指定すると、propsが不足していたり、型が異なる時などに、分かりやすいエラーメッセージが出てくるため、デバッグが楽になる。

```js:propTypesの指定例
const Hello = ({ name }) => (
  <div>Hello {name}</div>
);
Hello.propTypes = {
  name: React.PropTypes.string.isRequired,
};
```

```js:defaultpropsの書き方
const Hello = ({ name } = { name: 'World' }) => (
  <div>Hello {name}</div>
);
```

###5. コンポーネントを2種類に分類した例
・コンポーネントの役割を2種類に分ける
・「presentational component」表示に特化するコンポーネント
・「container component」データの処理を扱うコンポーネント
・分離すると、presentation componentがデータレイヤから切り離されるため、再利用性が上がるというメリットがあります。

```js
const Hello = ({ name, onClickButton }) => (
  <div>
    Hello {name}
    <button onClick={onClickButton}>Click me</button>
  </div>
);

const HelloContainer = ({ store }) => (
  <Hello
    name={store.getState().name}
    onClickButton={store.dispatch({ type: 'CHANGE_NAME_RANDOMLY' })}
  />
);
```








#Reduxとは
・Reduxはimmutabilityを基本としたUIの状態を管理するためのフレームワーク。

##Application Stateとは
・アプリケーションの状態で、単一のデータ構造で表現するもの。
・状態を保持する変数を一箇所に集中して管理する。

```js
let state = {
  inputValue: 0,
  resultValue: 0,
  showingResult: false,
};
```

##Actionとは
・actionはstateを変化させる操作のっこと
・actionはtypeプロパティを持つ**オブジェクト**
・actionには任意のプロパティを追加することができる。

```js
const action = { type: 'PLUS' };
const action1 = { type: 'INPUT_NUMBER', number: 1 };
const action2 = { type: 'INPUT_NUMBER', number: 2 };
```

##ActionCreaterとは
・Actionを作る関数
・必須ではない

```js:パラメータを受け取ってActionを返す関数
const doPlus = () => ({
  type: 'PLUS',
});

const inputNumber = (number) => ({
  type: 'INPUT_NUMBER',
  number,
});

console.log(doPlus());
console.log(inputNumber(3));
console.log(inputNumber(4));
console.log(inputNumber(5));
```

##Reducer
・stateとactionを入力とし、新しいstateを返す関数
・actionはstateを変化させる操作
・stateを変化させることができるのはreducer
・状態と状態操作を受け取り新しい状態を作る関数
例)新しい状態 = Reducer(今の状態, 状態操作);
state = reducer(state, action);

##Store
・application stateを管理する場所


#React環境構築
・VirtualBox centos7

###(1)Node.js / npm導入
・NVMで導入する

```bash:nvm導入
#nvmをクローン
git clone git://github.com/creationix/nvm.git ~/.nvm
#.bashrcに、nvmを登録
echo . ~/.nvm/nvm.sh >> ~/.bashrc
#.bashrc再読み込み
. ~/.bashrc
#nodeのインストール
nvm install stable
```

###(2)プロジェクトの初期化

```bash
mkdir プロジェクト名
cd プロジェクト名
npm init
```
=>「package.json」が作成される

###(3)webpackのインストール
npm install --save webpack

###(4)React / Babelのインストール
npm install --save react react-don

| モジュール名 | 概要 |
|:--|:-:|
|react|   |
|react-dom|   |


npm install --save babel-core babel-loader babel-preset-es2015 babel-preset-react

| モジュール名 | 概要 |
|:--|:-:|
|babel-core|   |
|babel-loader|   |
|babel-preset-es2015|   |
|babel-preset-react|   |

###()トップページのhtmlを自動生成するPlugin
npm install --save-dev html-webpack-plugin

###(5)webpackの設定ファイルを作成
・webpackを実行する際の設定ファイル

```js:webpack.config.js
const path = require('path');

module.exports = {
    entry: {
        bundle: './src/app.js'
    },
    output: {
        path: path.join(__dirname, 'public'),
        filename: '[name].js'
    },
    module: {
        loaders: [
            {
                loader: 'babel',
                exclude: /node_modules/,
                test: /\.js[x]?$/,
                query: {
                    cacheDirectory: true,
                    presets: ['react', 'es2015']
                }
            }
        ]
    }
};
```

| webpackコマンド | 概要 |
|:--|:--|
|context|entryオプションを解決するためのベースとなる絶対パス|
|devtool|ブラウザの開発者ツールなどでビルド前のコードを参照することができる|
|entry|ビルドの起点となるファイルのパスを指定する|
|output.path|出力先のパス|
|output.filename|出力ファイル名|
|module.loaders|対象のファイルを変換するためのloaderを指定。|
|module.loaders.test|Loaderを適用するファイルを指定する|
|module.loaders.loader|通すLoaderを指定する。|
|plugins||
|resolve||


```js
loaders: [
  {
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    query:{
      presets: ['react', 'es2015']
    }
  }
]
```
node_modules ディレクトリ配下を除き、拡張子が .js のファイルすべてに対し、babel-loader という loader を適用します。
また、適用する際、loader に react と es2015 という preset を指定します。