title: Creating a grid component in React - confused where to put state
body: <p>I'm a React novice. I'm building a generic grid component with a check column (similar to the Gmail inbox) so the user can easily select multiple rows (or all rows by clicking the checkbox in the header).</p>
  
  <p>The Grid component is composed of a GridHeader and GridRows (composed of GridCells).</p>
  
  <pre><code>        &lt;table className="grid"&gt;
              &lt;GridHeader ... /&gt;
              &lt;tbody&gt;
                  {rows}
              &lt;/tbody&gt;
          &lt;/table&gt;
  </code></pre>
  
  <p>For each GridRow, I'm rendering a checkbox in the first column which toggles the "selected" state for that row.</p>
  
  <pre><code>&lt;input type='checkbox' checked={selected} onChange={this.handleChange}/&gt;
  
  ...
  
  handleChange: function (event) {
      this.setState({selected: event.target.checked});
  },
  </code></pre>
  
  <p>That works fine as far as updating the UI:</p>
  
  <p><img src="https://i.stack.imgur.com/pgMiK.png" alt="current UI"></p>
  
  <p>...but the user of this Grid component needs to somehow access the selected rows/records using an API call like this:</p>
  
  <pre><code>grid.getSelected()
  </code></pre>
  
  <p>It would be pretty inefficient if the getSelected() method had to iterate over every row to query its selected state.  So I was thinking of moving the selection state into the Grid's state. One concern I had was that now whenever the Grid's state.selected changes, it would cause the entire grid to be re-rendered.</p>
  
  <p>Alternatively, the grid may keep an array of selected items in a variable separate from the state:</p>
  
  <pre><code>getSelected() { return this.selected } // array of selected row indices
  </code></pre>
  
  <p>And each individual row can still keep their own selected state so the UI can be updated, but this <a href="http://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html" rel="nofollow noreferrer">may be an anti-pattern</a> as now there's no longer one source of truth for the selection model.</p>
  
  <p>Can someone guide me as to where to keep selection state for this grid?</p>
  
  <p>Also, if I do need to iterate over the rows from within the grid component, must I attach a ref to each row and iterate over the refs?</p>
  
  <p>I'm trying not to complicate this question too much, but keep in mind the grid needs to support a "select all" checkbox in the GridHeader which should select all rows in the grid (like in Gmail's inbox).</p>