title: Last rows in inner table don't expand in Fixed Data Table
body: <p>I use <a href="http://schrodinger.github.io/fixed-data-table-2/example-expanded-rows.html" rel="nofollow noreferrer">expanded rows</a> in fixed-data-table-2 component. I have 3 levels on inner tables:</p>
  
  <p><a href="https://i.stack.imgur.com/U3n7t.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/U3n7t.png" alt="enter image description here"></a></p>
  
  <p>If I click collapse cells in inner table (second nested level), rows don't expand and last nested table is not rendered. It occurs after first click of parent row, but after second click the table is rendered.</p>
  
  <p>What is more strange, this behaviour doesn't happen if
  a) I click first three rows of second table or
  b) if I expand first row in main(first) table</p>
  
  <p>It happens with last rows of second table if other than first row of main table is expanded.</p>
  
  <p>You can see this behaviour in <a href="https://imgur.com/KZSdg0b" rel="nofollow noreferrer">this</a> and <a href="https://imgur.com/wzmOXbM" rel="nofollow noreferrer">this</a> recording.</p>
  
  <p><a href="https://codesandbox.io/s/nk7l2j114" rel="nofollow noreferrer">codesandbox</a></p>
  
  <p><strong>CollapseCell.jsx</strong></p>
  
  <pre><code>import React from 'react';
  import { Cell } from 'fixed-data-table-2';
  
  const { StyleSheet, css } = require('aphrodite');
  
  export default class CollapseCell extends React.PureComponent {
    render() {
      const {
        data, rowIndex, columnKey, collapsedRows, callback, ...props
      } = this.props;
      return (
        &lt;Cell {...props} className={css(styles.collapseCell)}&gt;
          &lt;a onClick={evt =&gt; callback(rowIndex)}&gt;{collapsedRows.has(rowIndex) ? '\u25BC' : '\u25BA'}&lt;/a&gt;
        &lt;/Cell&gt;
      );
    }
  }
  
  const styles = StyleSheet.create({
    collapseCell: {
      cursor: 'pointer',
    },
  });
  </code></pre>
  
  <p><strong>TestMeet.jsx</strong></p>
  
  <pre><code>import React, { Component } from 'react';
  import debounce from 'lodash/debounce';
  import { Table, Column, Cell } from 'fixed-data-table-2';
  import isEmpty from 'lodash/isEmpty';
  import 'fixed-data-table-2/dist/fixed-data-table.min.css';
  import CollapseCell from './CollapseCell.jsx';
  import SecondInnerTable from './SecondInnerTable';
  
  const { StyleSheet, css } = require('aphrodite');
  
  export default class TestMeetView extends Component {
    static propTypes = {};
  
    state = {
      tableData: [
        {
          start: '5/19',
          end: '5/20',
          host: 'DACA',
        },
        {
          start: '6/15',
          end: '6/15',
          host: 'DACA',
        },
        {
          start: '6/16',
          end: '6/17',
          host: 'DACA',
        },
        {
          start: '7/15',
          end: '7/16',
          host: 'DACA',
        },
        {
          start: '7/30',
          end: '7/31',
          host: 'DACA',
        },
      ],
      columnWidths: {
        start: 200,
        end: 200,
        host: 200,
        action: 100,
      },
      tableContainerWidth: 0,
      numOfExpRows: 0,
      expChildRows: {},
      collapsedRows: new Set(),
      scrollToRow: null,
    };
  
    componentDidMount() {
      this.updateWidth();
      this.updateWidth = debounce(this.updateWidth, 200);
      window.addEventListener('resize', this.updateWidth);
    }
  
    componentWillUnmount() {
      window.removeEventListener('resize', this.updateWidth);
    }
  
    onTableColumnResizeEndCallback = (newColumnWidth, columnKey) =&gt; {
      this.setState(({ columnWidths }) =&gt; ({
        columnWidths: {
          ...columnWidths,
          [columnKey]: newColumnWidth,
        },
      }));
    };
  
    updateWidth = () =&gt; {
      if (this.tableContainer.offsetWidth === this.state.tableContainerWidth) {
        return;
      }
  
      if (
        this.tableContainer &amp;&amp;
        this.tableContainer.offsetWidth !== this.state.tableContainerWidth
      ) {
        const newTableContainerWidth = this.tableContainer.offsetWidth;
        this.setState({
          tableContainerWidth: newTableContainerWidth,
          columnWidths: {
            start: newTableContainerWidth / 3,
            end: newTableContainerWidth / 3,
            host: newTableContainerWidth / 3,
          },
        });
      }
    };
  
    handleCollapseClick = (rowIndex) =&gt; {
      const { collapsedRows } = this.state;
      const shallowCopyOfCollapsedRows = new Set([...collapsedRows]);
      let scrollToRow = rowIndex;
      if (shallowCopyOfCollapsedRows.has(rowIndex)) {
        shallowCopyOfCollapsedRows.delete(rowIndex);
        scrollToRow = null;
      } else {
        shallowCopyOfCollapsedRows.add(rowIndex);
      }
  
      let numOfExpRows = 0;
      if (collapsedRows.size &gt; 0) {
        numOfExpRows = collapsedRows.size;
      }
  
      let resetExpChildRow = -1;
      if (collapsedRows.has(rowIndex)) {
        numOfExpRows -= 1;
        resetExpChildRow = rowIndex;
      } else {
        numOfExpRows += 1;
      }
  
      if (resetExpChildRow === -1) {
        this.setState({
          numOfExpRows,
          scrollToRow,
          collapsedRows: shallowCopyOfCollapsedRows,
        });
      } else {
        this.setState({
          numOfExpRows,
          scrollToRow,
          collapsedRows: shallowCopyOfCollapsedRows,
          expChildRows: {
            ...this.state.expChildRows,
            [rowIndex]: 0,
          },
        });
      }
    };
  
    subRowHeightGetter = (index) =&gt; {
      const numExpChildRows = this.state.expChildRows[index] ? this.state.expChildRows[index] : 0;
      return this.state.collapsedRows.has(index) ? 242 * (numExpChildRows + 1) + 50 : 0;
    };
  
    rowExpandedGetter = ({ rowIndex, width, height }) =&gt; {
      if (!this.state.collapsedRows.has(rowIndex)) {
        return null;
      }
  
      const style = {
        height,
        width: width - 10,
      };
  
      return (
        &lt;div style={style}&gt;
          &lt;div className={css(styles.expandStyles)}&gt;
            &lt;SecondInnerTable
              changeNumOfExpandedRows={this.setNumOfInnerExpandedRows}
              parentRowIndex={rowIndex}
            /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      );
    };
  
    setNumOfInnerExpandedRows = (numOfExpandedRows, rowIndex) =&gt; {
      this.setState({
        expChildRows: {
          ...this.state.expChildRows,
          [rowIndex]: numOfExpandedRows,
        },
      });
    };
  
    render() {
      let sumOfExpChildRows = 0;
      if (!isEmpty(this.state.expChildRows)) {
        sumOfExpChildRows = Object.values(this.state.expChildRows).reduce((a, b) =&gt; a + b);
      }
      return (
        &lt;div className="test-view"&gt;
          &lt;div className="container-fluid"&gt;
            &lt;div className="mb-5" ref={el =&gt; (this.tableContainer = el)}&gt;
              &lt;Table
                scrollToRow={this.state.scrollToRow}
                rowsCount={this.state.tableData.length}
                rowHeight={40}
                headerHeight={40}
                width={this.state.tableContainerWidth}
                height={(this.state.numOfExpRows + sumOfExpChildRows + 1) * 242}
                subRowHeightGetter={this.subRowHeightGetter}
                rowExpanded={this.rowExpandedGetter}
                touchScrollEnabled
                onColumnResizeEndCallback={this.onTableColumnResizeEndCallback}
                isColumnResizing={false}
              &gt;
                &lt;Column
                  cell={&lt;CollapseCell callback={this.handleCollapseClick} collapsedRows={this.state.collapsedRows} /&gt;}
                  fixed
                  width={30}
                /&gt;
                &lt;Column
                  columnKey="start"
                  header={&lt;Cell&gt;Start&lt;/Cell&gt;}
                  cell={props =&gt; &lt;Cell {...props}&gt;{this.state.tableData[props.rowIndex].start}&lt;/Cell&gt;}
                  width={this.state.columnWidths.start}
                  isResizable
                /&gt;
                &lt;Column
                  columnKey="end"
                  header={&lt;Cell&gt;End&lt;/Cell&gt;}
                  cell={props =&gt; &lt;Cell {...props}&gt;{this.state.tableData[props.rowIndex].end}&lt;/Cell&gt;}
                  width={this.state.columnWidths.end}
                  isResizable
                /&gt;
                &lt;Column
                  columnKey="host"
                  header={&lt;Cell&gt;Host&lt;/Cell&gt;}
                  cell={props =&gt; &lt;Cell {...props}&gt;{this.state.tableData[props.rowIndex].host}&lt;/Cell&gt;}
                  width={this.state.columnWidths.host}
                  isResizable
                /&gt;
              &lt;/Table&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      );
    }
  }
  
  const styles = StyleSheet.create({
    expandStyles: {
      height: '242px',
      margin: '10px',
    },
  });
  </code></pre>
  
  <p><strong>SecondInnerTable.jsx</strong></p>
  
  <pre><code>import React, { Component } from 'react';
  import { Table, Column, Cell } from 'fixed-data-table-2';
  import debounce from 'lodash/debounce';
  import 'fixed-data-table-2/dist/fixed-data-table.min.css';
  import CollapseCell from './CollapseCell';
  import ThirdInnerTable from './ThirdInnerTable';
  
  const { StyleSheet, css } = require('aphrodite');
  
  export default class SecondInnerTable extends Component {
    state = {
      tableData: [
        {
          dateOfSession: '5/19/18',
          timeline: '4h00m/4h30m',
          entries: '400/900',
        },
        {
          dateOfSession: '5/19/18',
          timeline: '4h00m/4h30m',
          entries: '400/900',
        },
        {
          dateOfSession: '5/19/18',
          timeline: '4h00m/4h30m',
          entries: '400/900',
        },
        {
          dateOfSession: '5/19/18',
          timeline: '4h00m/4h30m',
          entries: '400/900',
        },
        {
          dateOfSession: '5/19/18',
          timeline: '4h00m/4h30m',
          entries: '400/900',
        },
      ],
      tableColumns: {
        dateOfSession: { label: 'Date of Session', width: 150 },
        timeline: { label: 'Timeline', width: 150 },
        entries: { label: 'Entries', width: 150 },
      },
      tableContainerWidth: 0,
      tableContainerHeight: 252,
      collapsedRows: new Set(),
      scrollToRow: null,
    };
  
    componentDidMount() {
      this.updateWidth();
      this.updateWidth = debounce(this.updateWidth, 200);
      window.addEventListener('resize', this.updateWidth);
    }
  
    componentWillUnmount() {
      window.removeEventListener('resize', this.updateWidth);
    }
  
    onSessionsTableColumnResizeEndCallback = (newColumnWidth, columnKey) =&gt; {
      this.setState(({ tableColumns }) =&gt; ({
        tableColumns: {
          ...tableColumns,
          [columnKey]: { label: tableColumns[columnKey].label, width: newColumnWidth },
        },
      }));
    };
  
    updateWidth = () =&gt; {
      if (this.tableContainer.offsetWidth === this.state.tableContainerWidth) {
        return;
      }
      if (
        this.tableContainer &amp;&amp;
        this.tableContainer.offsetWidth !== this.state.tableContainerWidth
      ) {
        const newTableContainerWidth = this.tableContainer.offsetWidth - 20;
        const newColumnsWidth = newTableContainerWidth / 3;
        this.setState(({ tableColumns }) =&gt; ({
          tableContainerWidth: newTableContainerWidth,
          tableColumns: {
            dateOfSession: { label: tableColumns.dateOfSession.label, width: newColumnsWidth },
            timeline: { label: tableColumns.timeline.label, width: newColumnsWidth },
            entries: { label: tableColumns.entries.label, width: newColumnsWidth },
          },
        }));
      }
    };
  
    handleCollapseClick = (rowIndex) =&gt; {
      const { collapsedRows } = this.state;
      const shallowCopyOfCollapsedRows = new Set([...collapsedRows]);
      let scrollToRow = rowIndex;
      if (shallowCopyOfCollapsedRows.has(rowIndex)) {
        shallowCopyOfCollapsedRows.delete(rowIndex);
        scrollToRow = null;
      } else {
        shallowCopyOfCollapsedRows.add(rowIndex);
      }
  
      let numOfExpRows = 0;
      if (collapsedRows.size &gt; 0) {
        numOfExpRows = collapsedRows.size;
      }
  
      if (collapsedRows.has(rowIndex)) {
        numOfExpRows -= 1;
      } else {
        numOfExpRows += 1;
      }
  
      this.setState(
        {
          tableContainerHeight: 252 * (numOfExpRows + 1),
          scrollToRow,
          collapsedRows: shallowCopyOfCollapsedRows,
        },
        () =&gt; {
          this.props.changeNumOfExpandedRows(numOfExpRows, this.props.parentRowIndex);
        },
      );
    };
  
    subRowHeightGetter = index =&gt; (this.state.collapsedRows.has(index) ? 272 : 0);
  
    rowExpandedGetter = ({ rowIndex, width, height }) =&gt; {
      if (!this.state.collapsedRows.has(rowIndex)) {
        return null;
      }
  
      const style = {
        height,
        width: width - 10,
      };
      return (
        &lt;div style={style}&gt;
          &lt;div className={css(styles.expandStyles)}&gt;
            &lt;ThirdInnerTable parentRowIndex={rowIndex} /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      );
    };
  
    render() {
      return (
        &lt;div className="mb-2" ref={el =&gt; (this.tableContainer = el)}&gt;
          &lt;Table
            scrollToRow={this.state.scrollToRow}
            rowsCount={this.state.tableData.length}
            rowHeight={40}
            headerHeight={50}
            width={this.state.tableContainerWidth}
            height={this.state.tableContainerHeight}
            subRowHeightGetter={this.subRowHeightGetter}
            rowExpanded={this.rowExpandedGetter}
            touchScrollEnabled
            onColumnResizeEndCallback={this.onSessionsTableColumnResizeEndCallback}
            isColumnResizing={false}
          &gt;
            &lt;Column
              cell={&lt;CollapseCell callback={this.handleCollapseClick} collapsedRows={this.state.collapsedRows} /&gt;}
              fixed
              width={30}
            /&gt;
            {Object.keys(this.state.tableColumns).map(key =&gt; (
              &lt;Column
                key={key}
                columnKey={key}
                header={&lt;Cell&gt;{this.state.tableColumns[key].label}&lt;/Cell&gt;}
                cell={props =&gt; &lt;Cell {...props}&gt;{this.state.tableData[props.rowIndex][key]}&lt;/Cell&gt;}
                width={this.state.tableColumns[key].width}
                isResizable
              /&gt;
            ))}
          &lt;/Table&gt;
        &lt;/div&gt;
      );
    }
  }
  
  const styles = StyleSheet.create({
    expandStyles: {
      height: '252px',
      margin: '10px',
    },
  });
  </code></pre>
  
  <p><strong>ThirdInnerTable.jsx</strong></p>
  
  <pre><code>import React, { Component } from 'react';
  import debounce from 'lodash/debounce';
  import { Table, Column, Cell } from 'fixed-data-table-2';
  import 'fixed-data-table-2/dist/fixed-data-table.min.css';
  
  export default class ThirdInnerTable extends Component {
    state = {
      tableData: [
        {
          eventNumber: '1',
          qualifyingTime: 'N/A',
          selected: 'N/A',
        },
        {
          eventNumber: '1',
          qualifyingTime: 'N/A',
          selected: 'N/A',
        },
        {
          eventNumber: '1',
          qualifyingTime: 'N/A',
          selected: 'N/A',
        },
        {
          eventNumber: '1',
          qualifyingTime: 'N/A',
          selected: 'N/A',
        },
        {
          eventNumber: '1',
          qualifyingTime: 'N/A',
          selected: 'N/A',
        },
      ],
      tableColumns: {
        eventNumber: { label: 'Event number', width: 150 },
        qualifyingTime: { label: 'Qualifying time', width: 150 },
        selected: { label: 'Selected?', width: 150 },
      },
      tableContainerWidth: 0,
      numOfColumns: 3,
    };
  
    componentDidMount() {
      this.updateWidth();
      this.updateWidth = debounce(this.updateWidth, 200);
      window.addEventListener('resize', this.updateWidth);
    }
  
    componentWillUnmount() {
      window.removeEventListener('resize', this.updateWidth);
    }
  
    onEventsTableColumnResizeEndCallback = (newColumnWidth, columnKey) =&gt; {
      this.setState(({ tableColumns }) =&gt; ({
        tableColumns: {
          ...tableColumns,
          [columnKey]: { label: tableColumns[columnKey].label, width: newColumnWidth },
        },
      }));
    };
  
    updateWidth = () =&gt; {
      if (this.tableContainer.offsetWidth === this.state.tableContainerWidth) {
        return;
      }
      if (
        this.tableContainer &amp;&amp;
        this.tableContainer.offsetWidth !== this.state.tableContainerWidth
      ) {
        const newTableContainerWidth = this.tableContainer.offsetWidth;
        const columnWidth = newTableContainerWidth / 3;
  
        this.setState(({ tableColumns }) =&gt; ({
          tableContainerWidth: newTableContainerWidth,
          tableColumns: {
            eventNumber: { label: tableColumns.eventNumber.label, width: columnWidth },
            qualifyingTime: { label: tableColumns.qualifyingTime.label, width: columnWidth },
            selected: { label: tableColumns.selected.label, width: columnWidth },
          },
        }));
      }
    };
  
    render() {
      return (
        &lt;div className="mb-5" ref={el =&gt; (this.tableContainer = el)}&gt;
          &lt;Table
            rowsCount={this.state.tableData.length}
            rowHeight={40}
            headerHeight={50}
            width={this.state.tableContainerWidth}
            height={252}
            touchScrollEnabled
            onColumnResizeEndCallback={this.onEventsTableColumnResizeEndCallback}
            isColumnResizing={false}
          &gt;
            {Object.keys(this.state.tableColumns).slice(0, this.state.numOfColumns).map(key =&gt; (
              &lt;Column
                key={key}
                columnKey={key}
                header={&lt;Cell&gt;{this.state.tableColumns[key].label}&lt;/Cell&gt;}
                cell={props =&gt; &lt;Cell {...props}&gt;{this.state.tableData[props.rowIndex][key]}&lt;/Cell&gt;}
                width={this.state.tableColumns[key].width}
                isResizable
              /&gt;
              ))}
          &lt;/Table&gt;
        &lt;/div&gt;
      );
    }
  }
  </code></pre>