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

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));
  <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>

Leave a Reply

Your email address will not be published. Required fields are marked *