A fast, lightweight, opinionated table and datagrid built on React
- Lightweight at 3kb (and just 2kb more for styles)
- Fully customizable JSX and callbacks for everything
- Supports both Client-side & Server-side pagination and sorting
- Minimal design & easily themeable
- Installation
- Example
- Data
- Default Props
- Columns
- Styles
- Header Groups
- Server-side Data
- Multi-sort
- Component Overrides
$ npm install react-table
import ReactTable from 'react-table'
const data = [{
name: 'Tanner Linsley',
age: 26,
friend: {
name: 'Jason Maurer',
age: 23,
}
},{
...
}]
const columns = [{
header: 'Name',
accessor: 'name',
}, {
header: 'Age',
accessor: 'age'
}, {
header: 'Friend Name',
accessor: d => d.friend.name
}, {
header: 'Friend Age',
accessor: 'friend.age'
}]
<ReactTable
data=[data]
columns={columns}
/>
Every React-Table instance requires you to set the data
prop. To use client-side data, simply pass the data
prop anything that resembles an array or object. Client-side filtering and pagination is built in, and your table will update gracefully if you change any props. Server-side data is also supported.
These are the default props for the main react component <ReactTable />
{
// General
pageSize: 20,
minRows: 0, // Ensure this many rows are always rendered, regardless of rows on page
// Text
previousText: 'Previous',
nextText: 'Next'
// Classes
className: '-striped -highlight', // The most top level className for the component
tableClassName: '', // ClassName for the `table` element
theadClassName: '', // ClassName for the `thead` element
tbodyClassName: '', // ClassName for the `tbody` element
trClassName: '', // ClassName for all `tr` elements
trClassCallback: row => null, // A call back to dynamically add classes (via the classnames module) to a row element
paginationClassName: '' // ClassName for `pagination` element
// Styles
style: {}, // Main style object for the component
tableStyle: {}, // style object for the `table` component
theadStyle: {}, // style object for the `thead` component
tbodyStyle: {}, // style object for the `tbody` component
trStyle: {}, // style object for the `tr` component
trStyleCallback: row => {}, // A call back to dynamically add styles to a row element
thStyle: {}, // style object for the `th` component
tdStyle: {}, // style object for the `td` component
paginationStyle: {}, // style object for the `paginination` component
}
You can easily override the core defaults like so:
import { ReactTableDefaults } from 'react-table'
Object.assign(ReactTableDefaults, {
pageSize: 10,
minRows: 3,
// etc...
})
Or just define them on the component per-instance
<ReactTable
pageSize={10}
minRows={3}
// etc...
/>
Every React-Table instance requires a columns
prop, which is an array of objects containing the following properties
[{
// General
accessor: 'propertyName' or Accessor eg. (row) => row.propertyName,
id: 'myProperty', // Conditional - A unique ID is required if the accessor is not a string or if you would like to override the column name used in server-side calls
sortable: true,
sort: 'asc' or 'desc',
show: true,
minWidth: Number // Allows the column to flex above this minimum amount
// Cell Options
className: '', // Set the classname of the `td` element of the column
style: {}, // Set the style of the `td` element of the column
innerClassName: '', // Set the classname of the `.-td-inner` element of the column
innerStyle: {}, // Set the style of the `.-td-inner` element of the column
render: JSX eg. ({value, rowValues, row, index, viewIndex}) => <span>{value}</span>, // Provide a JSX element or stateless function to render whatever you want as the column's cell with access to the entire row
// value == the accessed value of the column
// rowValues == an object of all of the accessed values for the row
// row == the original row of data supplied to the table
// index == the original index of the data supplied to the table
// viewIndex == the index of the row in the current page
// Header & HeaderGroup Options
header: 'Header Name' or JSX eg. ({data, column}) => <div>Header Name</div>,
headerClassName: '', // Set the classname of the `th` element of the column
headerStyle: {}, // Set the style of the `th` element of the column
headerInnerClassName: '', // Set the classname of the `.-th-inner` element of the column
headerInnerStyle: {}, // Set the style of the `.th-inner` element of the column
// Header Groups only
columns: [...] // See Header Groups section below
}]
React-table is built to be dropped into existing applications or styled from the ground up, but if you'd like a decent starting point, you can optionally include our default theme react-table.css
. We think it looks great, honestly :)
To group columns with another header column, just nest your columns in a header column like so:
const columns = [{
header: 'Favorites',
columns: [{
header: 'Color',
accessor: 'favorites.color'
}, {
header: 'Food',
accessor: 'favorites.food'
} {
header: 'Actor',
accessor: 'favorites.actor'
}]
}]
If you want to handle pagination, and sorting on the server, react-table
makes it easy on you.
- Feed React Table
data
from somewhere dynamic. eg.state
, a redux store, etc... - Add
manual
as a prop. This informs React Table that you'll be handling sorting and pagination server-side - Subscribe to the
onChange
prop. This function is called any time sorting or pagination is changed by the user - In the
onChange
callback, request your data using the provided information in the params of the function (state and instance) - Update your data with the rows to be displayed
- Optionally set how many pages there are total
<ReactTable
...
data={this.state.data} // should default to []
pages={this.state.pages} // should default to -1 (which means we don't know how many pages we have)
manual // informs React Table that you'll be handling sorting and pagination server-side
onChange={(state, instance) => {
Axios.post('mysite.com/data', {
page: state.page,
pageSize: state.pageSize,
sorting: state.sorting
})
.then((res) => {
this.setState({
data: res.data.rows,
pages: res.data.pages
})
})
}}
/>
For a detailed example, take a peek at our async table mockup
When clicking on a column header, hold shift to multi-sort! You can toggle ascending
descending
and none
for multi-sort columns. Clicking on a header without holding shift will clear the multi-sort and replace it with the single sort of that column. It's quite handy!
Though we wouldn't suggest it, react-table
has the ability to change the core componentry it used to render it's table. You can do so by assigning a react component to it's corresponding global prop, or on a one-off basis like so:
// Change the global default
import { ReactTableDefaults } from 'react-table'
Object.assign(ReactTableDefaults, {
tableComponent: Component,
theadComponent: Component,
tbodyComponent: Component,
trComponent: Component,
thComponent: Component,
tdComponent: Component,
paginationComponent: Component,
previousComponent: Component,
nextComponent: Component,
loadingComponent: Component
})
// Or change per instance
<ReactTable
tableComponent={Component},
theadComponent={Component},
// etc...
/>
If you choose to change the core components React-Table uses to render, you must make sure your components support and utilized all of the neeeded features for that component to work properly. For a broad reference on how to do this, investigate the source for the component you wish to replace.
To suggest a feature, create an issue if it does not already exist. If you would like to help develop a suggested feature follow these steps:
- Fork this repo
npm install
npm watch
- Implement your changes to files in the
src/
directory - Submit PR for review
If you would like to preview your changes, you can link and utilize the example like so:
npm link
cd example
npm install
npm link react-table
npm watch
- Make changes to the example in
src/screens/index.js
if needed - View changes at
localhost:8000