react-data-grid vs react-spreadsheet vs react-datasheet
React Data Grid Libraries Comparison
1 Year
react-data-gridreact-spreadsheetreact-datasheetSimilar Packages:
What's React Data Grid Libraries?

React data grid libraries provide developers with powerful tools to create interactive and feature-rich data tables within React applications. These libraries facilitate the display, editing, and manipulation of tabular data, enhancing user experience and productivity. They come with various features such as sorting, filtering, and pagination, allowing for efficient data management. Each library has its unique strengths, catering to different use cases and developer preferences, making it essential to choose the right one based on project requirements.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
react-data-grid171,1837,127370 kB14419 days agoMIT
react-spreadsheet42,9511,402318 kB328 months agoMIT
react-datasheet28,4195,419118 kB128-MIT
Feature Comparison: react-data-grid vs react-spreadsheet vs react-datasheet

Customization

  • react-data-grid:

    react-data-grid offers extensive customization options, allowing developers to define custom cell renderers, editors, and styles. This flexibility enables the creation of tailored solutions that fit specific application needs, making it ideal for complex data scenarios.

  • react-spreadsheet:

    react-spreadsheet is designed for ease of use with limited customization options. It focuses on providing a basic spreadsheet experience, which can be beneficial for projects that do not require extensive customization.

  • react-datasheet:

    react-datasheet provides a simpler customization model focused on inline editing and basic styling. While it allows for some level of customization, it is less extensive compared to react-data-grid, making it suitable for straightforward applications without complex requirements.

Performance

  • react-data-grid:

    react-data-grid is optimized for performance with features like row and column virtualization, which allows it to handle large datasets efficiently without compromising user experience. This makes it suitable for applications that require fast rendering and interaction with substantial amounts of data.

  • react-spreadsheet:

    react-spreadsheet is lightweight and performs adequately for small to medium datasets. However, it may not be the best choice for applications dealing with large volumes of data, as it lacks advanced performance optimizations.

  • react-datasheet:

    react-datasheet performs well with moderate datasets but may struggle with very large datasets due to its simpler architecture. It is best used in scenarios where the data size is manageable and performance is not a critical concern.

User Experience

  • react-data-grid:

    react-data-grid provides a rich user experience with features like keyboard navigation, drag-and-drop functionality, and customizable cell editing. These features enhance user interaction and make data manipulation intuitive, suitable for applications requiring advanced user engagement.

  • react-spreadsheet:

    react-spreadsheet delivers a straightforward user experience, focusing on simplicity. It is easy to implement and use, making it suitable for applications where users require basic data manipulation without the need for advanced features.

  • react-datasheet:

    react-datasheet offers a familiar spreadsheet-like interface that is easy for users to understand. Its inline editing capabilities make it user-friendly, especially for those accustomed to traditional spreadsheet applications, making it ideal for quick data entry tasks.

Integration

  • react-data-grid:

    react-data-grid integrates well with various state management libraries and can be easily combined with other React components. Its architecture supports complex integrations, making it a versatile choice for larger applications.

  • react-spreadsheet:

    react-spreadsheet is designed for quick integration, making it suitable for projects that need a basic grid without extensive setup. However, its simplicity may limit its use in more complex application architectures.

  • react-datasheet:

    react-datasheet is simple to integrate into existing React applications, especially when the requirements are minimal. It works well with basic state management but may require additional effort for more complex integrations.

Documentation and Community Support

  • react-data-grid:

    react-data-grid has comprehensive documentation and a strong community, providing ample resources for developers. This support makes it easier to troubleshoot issues and implement advanced features, enhancing developer experience.

  • react-spreadsheet:

    react-spreadsheet offers basic documentation, which is sufficient for simple use cases. However, the limited community support may pose challenges for developers looking for help with more complex scenarios.

  • react-datasheet:

    react-datasheet has decent documentation, but the community is smaller compared to react-data-grid. While it covers the basics, developers may find fewer resources for advanced use cases.

How to Choose: react-data-grid vs react-spreadsheet vs react-datasheet
  • react-data-grid:

    Choose react-data-grid if you need a highly customizable and performant grid solution that supports large datasets. It offers extensive features like virtualization, cell editing, and keyboard navigation, making it suitable for applications requiring complex data interactions.

  • react-spreadsheet:

    Select react-spreadsheet if you are looking for a lightweight solution that provides basic spreadsheet functionalities. It is perfect for projects that require a simple grid without extensive features, allowing for quick implementation and minimal setup.

  • react-datasheet:

    Opt for react-datasheet if you want a spreadsheet-like experience with a focus on simplicity and ease of use. It allows for inline editing and is ideal for applications where users need to manipulate data in a familiar spreadsheet format without the overhead of complex features.

README for react-data-grid

react-data-grid

npm-badge type-badge size-badge codecov-badge ci-badge

Features

Links

Install

npm install react-data-grid

react-data-grid is published as ECMAScript modules for evergreen browsers, bundlers, and server-side rendering.

Quick start

import 'react-data-grid/lib/styles.css';

import DataGrid from 'react-data-grid';

const columns = [
  { key: 'id', name: 'ID' },
  { key: 'title', name: 'Title' }
];

const rows = [
  { id: 0, title: 'Example' },
  { id: 1, title: 'Demo' }
];

function App() {
  return <DataGrid columns={columns} rows={rows} />;
}

API

Components

<DataGrid />

DataGridProps
columns: readonly Column<R, SR>[]

See Column.

An array describing the grid's columns.

:warning: Passing a new columns array will trigger a re-render for the whole grid, avoid changing it as much as possible for optimal performance.

rows: readonly R[]

An array of rows, the rows data can be of any type.

topSummaryRows?: Maybe<readonly SR[]>

An optional array of summary rows, usually used to display total values for example. topSummaryRows are pinned at the top of the rows view and the vertical scroll bar will not scroll these rows.

bottomSummaryRows?: Maybe<readonly SR[]>

An optional array of summary rows, usually used to display total values for example. bottomSummaryRows are pinned at the bottom of the rows view and the vertical scroll bar will not scroll these rows.

rowKeyGetter?: Maybe<(row: R) => K>

A function returning a unique key/identifier per row. rowKeyGetter is required for row selection to work.

import DataGrid from 'react-data-grid';

interface Row {
  id: number;
  name: string;
}

function rowKeyGetter(row: Row) {
  return row.id;
}

function MyGrid() {
  return <DataGrid columns={columns} rows={rows} rowKeyGetter={rowKeyGetter} />;
}

:bulb: While optional, setting this prop is recommended for optimal performance as the returned value is used to set the key prop on the row elements.

onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>

A function receiving row updates. The first parameter is a new rows array with both the updated rows and the other untouched rows. The second parameter is an object with an indexes array highlighting which rows have changed by their index, and the column where the change happened.

import { useState } from 'react';
import DataGrid from 'react-data-grid';

function MyGrid() {
  const [rows, setRows] = useState(initialRows);

  return <DataGrid columns={columns} rows={rows} onRowsChange={setRows} />;
}
rowHeight?: Maybe<number | ((row: R) => number)>

Default: 35 pixels

Either a number defining the height of row in pixels, or a function returning dynamic row heights.

headerRowHeight?: Maybe<number>

Default: 35 pixels

A number defining the height of the header row.

summaryRowHeight?: Maybe<number>

Default: 35 pixels

A number defining the height of summary rows.

selectedRows?: Maybe<ReadonlySet<K>>

A set of selected row keys. rowKeyGetter is required for row selection to work.

isRowSelectionDisabled?: Maybe<(row: NoInfer<R>) => boolean>

A function used to disable row selection on certain rows.

onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>

A function called when row selection is changed.

import { useState } from 'react';
import DataGrid, { SelectColumn } from 'react-data-grid';

const rows: readonly Rows[] = [...];

const columns: readonly Column<Row>[] = [
  SelectColumn,
  // other columns
];

function MyGrid() {
  const [selectedRows, setSelectedRows] = useState((): ReadonlySet<number> => new Set());

  return (
    <DataGrid
      rowKeyGetter={rowKeyGetter}
      columns={columns}
      rows={rows}
      selectedRows={selectedRows}
      isRowSelectionDisabled={isRowSelectionDisabled}
      onSelectedRowsChange={setSelectedRows}
    />
  );
}

function rowKeyGetter(row: Row) {
  return row.id;
}

function isRowSelectionDisabled(row: Row) {
  return !row.isActive;
}
sortColumns?: Maybe<readonly SortColumn[]>

An array of sorted columns.

onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>

A function called when sorting is changed

import { useState } from 'react';
import DataGrid, { SelectColumn } from 'react-data-grid';

const rows: readonly Rows[] = [...];

const columns: readonly Column<Row>[] = [
  {
    key: 'name',
    name: 'Name',
    sortable: true
  },
  // other columns
];

function MyGrid() {
  const [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]);

  return (
    <DataGrid
      columns={columns}
      rows={rows}
      sortColumns={sortColumns}
      onSortColumnsChange={setSortColumns}
    />
  );
}

Grid can be sorted on multiple columns using ctrl (command) + click. To disable multiple column sorting, change the onSortColumnsChange function to

onSortColumnsChange(sortColumns: SortColumn[]) {
  setSortColumns(sortColumns.slice(-1));
}
defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>

Column options that are applied to all the columns

function MyGrid() {
  return (
    <DataGrid
      columns={columns}
      rows={rows}
      defaultColumnOptions={{
        minWidth: 100,
        resizable: true,
        sortable: true,
        draggable: true
      }}
    />
  );
}
onFill?: Maybe<(event: FillEvent<R>) => R>
onCopy?: Maybe<(event: CopyEvent<R>) => void>
onPaste?: Maybe<(event: PasteEvent<R>) => R>
onCellClick?: Maybe<(args: CellClickArgs<R, SR>, event: CellMouseEvent) => void>

Triggered when a cell is clicked. The default behavior is to select the cell. Call preventGridDefault to prevent the default behavior

function onCellClick(args: CellClickArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventGridDefault();
  }
}

<DataGrid rows={rows} columns={columns} onCellClick={onCellClick} />;

This event can be used to open cell editor on single click

function onCellClick(args: CellClickArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventGridDefault();
    args.selectCell(true);
  }
}

Arguments:

args: CellClickArgs<R, SR>

  • args.rowIdx: number - row index of the currently selected cell
  • args.row: R - row object of the currently selected cell
  • args.column: CalculatedColumn<TRow, TSummaryRow> - column object of the currently selected cell
  • args.selectCell: (enableEditor?: boolean) => void - function to manually select the cell and optionally pass true to start editing

event extends React.MouseEvent<HTMLDivElement>

  • event.preventGridDefault:: () => void
  • event.isGridDefaultPrevented: boolean
onCellDoubleClick?: Maybe<(args: CellClickArgs<R, SR>, event: CellMouseEvent) => void>

Triggered when a cell is double clicked. The default behavior is to open the editor if the cell is editable. Call preventGridDefault to prevent the default behavior

function onCellDoubleClick(args: CellClickArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventGridDefault();
  }
}

<DataGrid rows={rows} columns={columns} onCellDoubleClick={onCellDoubleClick} />;
onCellContextMenu?: Maybe<(args: CellClickArgs<R, SR>, event: CellMouseEvent) => void>

Triggered when a cell is right clicked. The default behavior is to select the cell. Call preventGridDefault to prevent the default behavior

function onCellContextMenu(args: CellClickArgs<R, SR>, event: CellMouseEvent) {
  if (args.column.key === 'id') {
    event.preventGridDefault();
  }
}

<DataGrid rows={rows} columns={columns} onCellContextMenu={onCellContextMenu} />;
onCellKeyDown?: Maybe<(args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void>

A function called when keydown event is triggered on a cell. This event can be used to customize cell navigation and editing behavior.

Examples

  • Prevent editing on Enter
function onCellKeyDown(args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) {
  if (args.mode === 'SELECT' && event.key === 'Enter') {
    event.preventGridDefault();
  }
}
  • Prevent navigation on Tab
function onCellKeyDown(args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) {
  if (args.mode === 'SELECT' && event.key === 'Tab') {
    event.preventGridDefault();
  }
}

Check more examples

onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;

Triggered when the selected cell is changed.

Arguments:

  • args.rowIdx: number - row index
  • args.row: R - row object of the currently selected cell
  • args.column: CalculatedColumn<TRow, TSummaryRow> - column object of the currently selected cell
onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>

A function called when the grid is scrolled.

onColumnResize?: Maybe<(column: CalculatedColumn<R, SR>, width: number) => void>

A function called when column is resized.

enableVirtualization?: Maybe<boolean>

Default: true

This prop can be used to disable virtualization.

renderers?: Maybe<Renderers<R, SR>>

This prop can be used to override the internal renderers. The prop accepts an object of type

interface Renderers<TRow, TSummaryRow> {
  renderCell?: Maybe<(key: Key, props: CellRendererProps<TRow, TSummaryRow>) => ReactNode>;
  renderCheckbox?: Maybe<(props: RenderCheckboxProps) => ReactNode>;
  renderRow?: Maybe<(key: Key, props: RenderRowProps<TRow, TSummaryRow>) => ReactNode>;
  renderSortStatus?: Maybe<(props: RenderSortStatusProps) => ReactNode>;
  noRowsFallback?: Maybe<ReactNode>;
}

For example, the default <Row /> component can be wrapped via the renderRow prop to add contexts or tweak props

import DataGrid, { RenderRowProps, Row } from 'react-data-grid';

function myRowRenderer(key: React.Key, props: RenderRowProps<Row>) {
  return (
    <MyContext key={key} value={123}>
      <Row {...props} />
    </MyContext>
  );
}

function MyGrid() {
  return <DataGrid columns={columns} rows={rows} renderers={{ renderRow: myRowRenderer }} />;
}

:warning: To prevent all rows from being unmounted on re-renders, make sure to pass a static or memoized component to renderRow.

rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>

A function to add a class on the row

import DataGrid from 'react-data-grid';

function MyGrid() {
  return <DataGrid columns={columns} rows={rows} rowClass={rowClass} />;
}

function rowClass(row: Row, rowIdx: number) {
  return rowIdx % 2 === 0 ? 'even' : 'odd';
}
direction?: Maybe<'ltr' | 'rtl'>

This property sets the text direction of the grid, it defaults to 'ltr' (left-to-right). Setting direction to 'rtl' has the following effects:

  • Columns flow from right to left
  • Frozen columns are pinned on the right
  • Column resize handle is shown on the left edge of the column
  • Scrollbar is moved to the left
className?: string | undefined

custom classname

style?: CSSProperties | undefined

custom styles

'aria-label'?: string | undefined

The label of the grid. We recommend providing a label using aria-label or aria-labelledby

'aria-labelledby'?: string | undefined

The id of the element containing a label for the grid. We recommend providing a label using aria-label or aria-labelledby

'aria-description'?: string | undefined
'aria-describedby'?: string | undefined

If the grid has a caption or description, aria-describedby can be set on the grid element with a value referring to the element containing the description.

'data-testid'?: Maybe<string>

This prop can be used to add a testid for testing. We recommend using role and name to find the grid element

function MyGrid() {
  return <DataGrid aria-label="my-grid" columns={columns} rows={rows} />;
}

function MyGridTest() {
  const grid = screen.getByRole('grid', { name: 'my-grid' });
}

<TreeDataGrid />

TreeDataGrid is component built on top of DataGrid to add row grouping. This implements the Treegrid pattern. At the moment TreeDataGrid does not support onFill and isRowSelectionDisabled props

TreeDataGridProps
groupBy?: Maybe<readonly string[]>
rowGrouper?: Maybe<(rows: readonly R[], columnKey: string) => Record<string, readonly R[]>>
expandedGroupIds?: Maybe<ReadonlySet<unknown>>
onExpandedGroupIdsChange?: Maybe<(expandedGroupIds: Set<unknown>) => void>

<TextEditor />

Props

See RenderEditCellProps

<Row />

See renderers

Props

See RenderRowProps

The ref prop is supported.

<SortableHeaderCell />

Props
onSort: (ctrlClick: boolean) => void
sortDirection: SortDirection | undefined
priority: number | undefined
tabIndex: number
children: React.ReactNode

<ValueFormatter />

Props

See FormatterProps

<SelectCellFormatter />

Props
value: boolean
tabIndex: number
disabled?: boolean | undefined
onChange: (value: boolean, isShiftClick: boolean) => void
onClick?: MouseEventHandler<T> | undefined
'aria-label'?: string | undefined
'aria-labelledby'?: string | undefined

<ToggleGroupFormatter />

Props

See RenderGroupCellProps

Hooks

useHeaderRowSelection<R>(): { isIndeterminate, isRowSelected, onRowSelectionChange }

useRowSelection<R>(): { isRowSelectionDisabled, isRowSelected, onRowSelectionChange }

Other

SelectColumn: Column<any, any>

SELECT_COLUMN_KEY = 'rdg-select-column'

Types

Column

name: string | ReactElement

The name of the column. By default it will be displayed in the header cell

key: string

A unique key to distinguish each column

width?: Maybe<number | string>

Default auto

Width can be any valid css grid column value. If not specified, it will be determined automatically based on grid width and specified widths of other columns.

width: 80; // pixels
width: '25%';
width: 'max-content';
width: 'minmax(100px, max-content)';

max-content can be used to expand the column to show all the content. Note that the grid is only able to calculate column width for visible rows.

minWidth?: Maybe<number>

Default: 50 pixels

Sets the maximum width of a column.

maxWidth?: Maybe<number>

Sets the maximum width of a column.

cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>

A function to add a class on the row

headerCellClass?: Maybe<string>
summaryCellClass?: Maybe<string | ((row: TSummaryRow) => Maybe<string>)>
renderCell?: Maybe<(props: RenderCellProps<TRow, TSummaryRow>) => ReactNode>

Render function used to render the content of cells

renderHeaderCell

Render function used to render the content of header cells

renderSummaryCell

Render function used to render the content of summary cells

DataGridHandle

RenderEditCellProps

RenderCellProps

RenderGroupCellProps

RenderRowProps

Generics

  • R, TRow: Row type
  • SR, TSummaryRow: Summary row type
  • K: Row key type