Blog>
Snippets

Using Memoization to Prevent Unnecessary Renders in Virtualized Table

Demonstrate the use of React's useMemo and useCallback hooks to memoize rows and columns in React TanStack Table, preventing unnecessary re-renders when virtualizing large datasets.
import React, { useMemo, useCallback } from 'react';
import { useTable } from 'react-table';
import { FixedSizeList as List } from 'react-window';
Imports React, useMemo, useCallback hooks, useTable from react-table, and List from react-window for virtualization.
const RenderRow = React.memo(({ index, style, data }) => {
  const row = data[index];
  return (
    <div {...row.getRowProps({ style })} className="tr">
      {row.cells.map(cell => {
        return (
          <div {...cell.getCellProps()} className="td">
            {cell.render('Cell')}
          </div>
        )
      })}
    </div>
  )
});
Defines a memoized row component. It only re-renders if the props change, thus preventing unnecessary renders for unchanged rows.
const Table = ({ columns, data }) => {
  const defaultColumn = useMemo(() => ({
    minWidth: 30,
    width: 150,
    maxWidth: 200
  }), []);

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable({
    columns,
    data,
    defaultColumn
  });

  const RenderedRows = useCallback(({ index, style }) => <RenderRow index={index} style={style} data={rows} prepareRow={prepareRow} />, [rows, prepareRow]);

  return (
    <div {...getTableProps()}>
      <div>
        {headerGroups.map(headerGroup => (
            <div {...headerGroup.getHeaderGroupProps()} className="tr">
              {headerGroup.headers.map(column => (
                  <div {...column.getHeaderProps()} className="th">
                    {column.render('Header')}
                  </div>
              ))}
            </div>
        ))}
      </div>
      <List
        height={400}
        itemCount={rows.length}
        itemSize={35}
        width={'100%'}
      >
        {RenderedRows}
      </List>
    </div>
  );
}
Creates the table component using useTable hook. Memoizes the defaultColumn definition and useCallback for row rendering to prevent unnecessary re-renders.