React Table Virtualization

Example that shows you how to apply this technique to a table.

HTML

<script src="https://unpkg.com/react@16.2.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.2.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/prop-types/prop-types.js"></script>
<div id='app'></div>

CSS

.wrapper {
  display: inline-block;
}

.wrapper table {
	border-style: none;
	/*border-collapse: collapse;*/
  /*display: block;*/
}

.table-content {
  overflow-y: scroll;
  border-collapse: collapse;
  display: block;
}

th {
	background-color: #333;
	color: #fcfcfc;
}

td {
	color: #333;
}

th, td {
	text-align: center;
	font-size: .6rem;
	font-weight: bold;
	text-transform: uppercase;
	font-family: sans-serif;
	width: 6rem;
}

.tr {
  height: 35px;
  max-height: 35px;
}

.tr-odd {
  background-color: #DADDE1;
}

.tr-even {
  background-color: #fcfcfc;
}

Babel + JSX

const { Component } = React
const { render, findDOMNode } = ReactDOM

class Table extends Component {
  constructor(props) {
    // Initial props:
    super(props)

    // Initial state:
    this.state = {
      columns: Object.keys(this.props.rows[0]),
      tableHeight: (this.props.rowHeight * this.props.rows.length),
      scroll: {
        top: 0,
        index: 0,
        end: Math.ceil((this.props.tableHeight * 2) / this.props.rowHeight)
      }
    }

    // Event handlers:
    this.onScroll = this.onScroll.bind(this)
    this.scrollInterval = null
  }

  onScroll({ target }) {
    let state = this.state;

    let scrollTop = target.scrollTop
    let rowHeight = this.props.rowHeight
    let tableHeight = this.props.tableHeight
    let index = Math.floor(scrollTop / rowHeight)

    state.scroll.index = index
    state.scroll.end = index + Math.ceil((tableHeight * 2) / rowHeight)
    state.scroll.top = (scrollTop / rowHeight) * rowHeight

    this.setState(state);
  }

  generateRows() {
    let columns = this.state.columns
    let rowHeight = this.props.rowHeight
    let rows = this.props.rows
    let index = this.state.scroll.index
    let end = this.state.scroll.end
    let items = []

    do {
      if (index >= rows.length) {
        index = rows.length
        break
      }

      const rowAttrs = {
        style: {
          position: "absolute",
          top: (index * rowHeight),
          left: 0,
          height: rowHeight,
          lineHeight: `${rowHeight}px`
        },
        className: `tr ${(index % 2) === 0 ? 'tr-odd' : 'tr-even'}`
      }

      items.push(
        <tr {...rowAttrs} key={index}>
          {columns.map((column, i) =>
            <td key={i}>
              {rows[index][column]}
            </td>
          )}
        </tr>
      )

      index++
    } while (index < end)

      return items
  }

  render() {
    const tableHeight = (this.props.tableHeight > this.state.tableHeight)
    ? this.state.tableHeight + 2
    :...