Reactノート1

###参照
https://www.to-r.net/media/react-tutorial05/

#トレーニング用gulp.js
(Gulp+Babel+Browserify+browser-sync)

暫定版

参考
http://qiita.com/kjugk/items/e23556bb1ca908dd6f6b

```gulpfile.js

'use strict';
var gulp = require('gulp');
var browserSync = require('browser-sync');
var gutil = require('gulp-util');
var browserify = require('browserify');
var watchify = require('watchify');
var bebelify = require('babelify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var sourcemaps = require('gulp-sourcemaps');

var b = browserify({
  entries: ['./js/index.js'],
  transform: ['babelify'],
  cache: {},
  packageCache: {},
  plugin: [watchify]
})
.on('update', bundle)
.on('log', gutil.log)

function bundle(){
  return b.bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify Error')  )
    .pipe(source('bundle.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./dist'));
}
gulp.task('browser-sync', function() {
    browserSync.init({
        server: {
            baseDir: "./",
            index: "index.html"
        }
    });
});
gulp.task('bs-reload', function () {
    browserSync.reload();
});
gulp.task('js', bundle);

gulp.task('default',['js','browser-sync'],function() {
  gulp.watch('./dist/bundle.js', ['bs-reload']);
});
```

![スクリーンショット 2017-02-22 20.00.08.png](https://qiita-image-store.s3.amazonaws.com/0/62264/902a9e74-4a8c-8ab1-e213-170dc1ac6ae3.png)


渡された値を使って動的にHTMLを生成する場合

どのDOMがいまどんな値を持っているのか
どのDOMから何のイベントが発火するか
この値が変わったらどのDOMを書き換えないといけないか

- 変更があったらHTML全体を書き換える

- 常に最新の状態のDOMをレンダリングする

- イベントハンドリングをやる

- 内部でdiff/patchしてくれる

- テストを書く

[設計]
サーバーにアクセスするのは、データ取得・保存するときだけにする。APIへ。


##JSX

- JS内に直接HTMLが書ける

- コンパイルするとDOM生成コードに変換する

- JSX内のコメントアウトは{}内に記述する

- 空要素は、最後を/で閉める

```
<img src="foo.jpg" alt="" />
```

- HTMLのclass属性は、ClassNameと書く

- HTMLのfor属性は、htmlForと書く

- input要素のvalue属性で初期値を設定すると値が変更できなくなるので、defaultValueと書く

- ラジオボタンやチェックボックスのcheked="cheked"にしてしまうと変更できなくなるので、defaultCheckedと書く

- styleは、{{この中に書く}}

- JavaScriptは{この中に書く}

- {}の中身はJSの式として解釈されるので変数だけでなく関数も使える

- 一度作成したコンポーネントはJSX内ではHTMLタグのように利用できる

#コンポーネント

- コンポーネントとは、UIパーツのロジックとマークアップが1箇所に定義されたもの


```index.js

import React from 'react'
import {render} from 'react-dom'

render(
  <div>
    <h1>title</h1>
    <h2>contents</h2>
  </div>,
  document.getElementById('root')
);

```

###React.createClassのrenderメソッドで作成の場合

- 作成したコンポーネントはJSX内でHTMLタグのように使える

```index.js

import React from 'react'
import {render} from 'react-dom'

var MyComponent = React.createClass({
render: function() {
  return (
    <div>
      <h1>title</h1>
      <h2>contents</h2>
    </div>
  )
}
});

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

###React.Componentを継承してコンポーネントを作成する場合

```index.js

  import React from 'react'
  import {render} from 'react-dom'

  class MyComponent extends React.Component {
    render() {
      return (
        <div>
          <h1>title</h1>
          <h2>contents</h2>
        </div>
      )
    }
  };

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

###function構文でコンポーネントを作成する(Stateless Functions)場合

```index.js

  import React from 'react'
  import {render} from 'react-dom'

  function MyComponent() {
    return (
      <div>
        <h1>title</h1>
        <h2>contents</h2>
      </div>
    )
  };
  render(
    <MyComponent />,
    document.getElementById('root')
  );
```

###コンポーネントを組み合わせる場合

```index.js

  import React from 'react'
  import {render} from 'react-dom'

function Title() {
  return (
    <h1>title</h1>
  )
}
function Contents() {
  return (
    <h2>contents</h2>
  )
}
function MyComponent() {
  return (
    <div>
      <Title />
      <Contents />
    </div>
  )
};

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

---

#1枚で試す

```index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>sample</title>
</head>
<body>
    <div id="app"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
    <script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script>
    <!-- babelがscript要素の内容をブラウザが解釈できるように変換を行う -->
    <script type="text/babel">
    ReactDOM.render(
        <h1>title</h1>,
        document.getElementById('app')
    );
    </script>
</body>
</html>
```

- ブラウザ上での変換はコスト高。コンパイルした方がよい。