Reactでcheckboxの状態をステートで管理する

[React (Facebook): managed state of controlled checkboxes](https://stackoverflow.com/questions/21581688/react-facebook-managed-state-of-controlled-checkboxes)のパクリと自分の理解のためのメモ

## index.htmlの準備

```
<!DOCTYPE html>
<html>
  <head>
  ¦ <meta charset="UTF-8" />
  ¦ <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.min.js"></script>
  ¦ <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.min.js"></script>
  ¦ <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
  ¦ <div id="content"></div>
    <script type="text/babel">
    // この中にReact書く
    </script>
  </body>
</html>
```

## ReactクラスとState定義
2つあるinputのcheckboxがそれぞれチェックされているかどうかの状態を持つためのstateを準備。ついでにReactDOMレンダーも定義。

```
var CheckboxDemo = React.createClass({
  getInitialState: function () {
    return {
      data: [
        {id: 1, selected: false },
        {id: 2, selected: false }
      ]
    };
  },
  // この下にFormを書く
});
ReactDOM.render(
  <CheckboxDemo />,
  document.getElementById('content')
);
```

## Form作成
Formの要素としてchecksを定義する。mapの中でCheckboxDemoオブジェクトにthisでアクセスできるようにbindしておく

```
render: function () {
  var checks = this.state.data.map(function (d) {
    return (
      <div>
        <input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} />
          {d.id}
          <br />
      </div>
    );
  }.bind(this));
  return (
    <form>
      {checks}
    </form>
  )
}
```

まだ理解できてないところとして__changeSelection.bind(this, d.id)のthisはCheckboxDemoなのかdなのか

## changeSelection定義
チェックボックスが押された時の__changeSelection関数を定義。チェックボックスが押されたらidを__changeSelectionを渡して呼び出して__changeSelectionの中でdataの中を全部チェックして、渡したidとdataのidが一致したらselectedの真偽値を変更してdataを丸ごと変更かける

```
__changeSelection: function (id) {
  var nextState = this.state.data.map(function (d) {
    return {
      id: d.id,
      selected: (d.id === id ? !d.selected: d.selected)
    };
  });

  console.log(nextState); // 確認用
  this.setState( {data: nextState });
},
```

## 全部チェックを実装
form内を修正

```
<form>
  <input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks } />CheckAll
  <br />
  {checks}
</form>
```

## changeAllChecksの定義
globalSelectorのチェックボックスがチェックされているかどうかをgetDOMNodeでとってきてchecksに入れて、checksをdataの全てのselectedに反映する

```
__changeAllChecks: function () {
  var chekcs = this.refs.globalSelector.getDOMNode().checked;
  var nextState = this.state.data.map(function (d) {
    return {id: d.id, selected: chekcs };
  });

  console.log('change all checks -> ', nextState)
  this.setState( { data: nextState })
}
```

## 全体コード

```
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
  </head>
  <body>
    <div id="content"></div>
    <script type="text/babel">

    var CheckboxDemo = React.createClass({
      getInitialState: function () {
        return {
          data: [
            {id: 1, selected: false },
            {id: 2, selected: false }
          ]
        };
      },

      render: function () {
        var checks = this.state.data.map(function (d) {
          return (
            <div>
              <input type="checkbox" checked={d.selected} onChange={this.__changeSelection.bind(this, d.id)} />
                {d.id}
                <br />
            </div>
          );
        }.bind(this));
        return (
          <form>
            <input type="checkbox" ref="globalSelector" onChange={this.__changeAllChecks } />CheckAll
            <br />
            {checks}
          </form>
        )
      },

      __changeSelection: function (id) {
        var nextState = this.state.data.map(function (d) {
          return {
            id: d.id,
            selected: (d.id === id ? !d.selected: d.selected)
          };
        });

        console.log(nextState);
        this.setState( {data: nextState });
      },

      __changeAllChecks: function () {
        var chekcs = this.refs.globalSelector.getDOMNode().checked;
        var nextState = this.state.data.map(function (d) {
          return {id: d.id, selected: chekcs };
        });

        console.log('change all checks -> ', nextState)
        this.setState( { data: nextState })
      }

    });



    ReactDOM.render(
      <CheckboxDemo />,
      document.getElementById('content')
    );
    </script>
  </body>
</html>
```