LoginSignup
19

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-29

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>

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19