Skip to main content

Optimization guidelines

Use React.memo()

It is recommended to wrap all cell components in React.memo() to avoid un-necessary renders (except for very light components where a re-render is faster than a props check):

const MyComponent = React.memo(({ rowData, setRowData }) => {
return <input {/*...*/} />
})

const column = { component: MyComponent, /*...*/ }

Use keyColumn

Cell components are re-rendered only when their props change thanks to React.memo(). But because they take the entire row object in the prop rowData (and not just the value they are interested in), all cells of a row are re-rendered when the user edits a single cell.

To make this obvious consider the following text-typed column:

// Do not do this 👎
const TextComponent = React.memo(
({ rowData, setRowData, columnData }) => {
return (
<input
value={rowData[columnData]}
onChange={(e) => setRowData({ ...rowData, [columnData]: e.target.value })}
/>
)
}
)

const textColumn = (key) => ({
component: TextComponent,
columnData: key,
deleteValue: ({ rowData }) => ({ ...rowData, [key]: '' }),
copyValue: ({ rowData }) => rowData[key],
pasteValue: ({ rowData, value }) => ({ ...rowData, [key]: value }),
})

const columns = [
{ ...textColumn('firstName') },
{ ...textColumn('lastName') },
]

The rowData prop of the firstName column will change every time the user changes the lastName (and vice-versa), triggering an un-necessary re-render of the firstName column. And this happens on every keystroke!

Fortunately this can easily be avoided by using the built-in keyColumn.

import { keyColumn } from 'react-datasheet-grid'

const TextComponent = React.memo(
({ rowData, setRowData }) => {
return (
<input
value={rowData}
onChange={(e) => setRowData(e.target.value)}
/>
)
}
)

const textColumn = {
component: TextComponent,
deleteValue: () => '',
copyValue: ({ rowData }) => rowData,
pasteValue: ({ value }) => value,
}

const columns = [
{ ...keyColumn('firstName', textColumn) }
{ ...keyColumn('lastName', textColumn) }
]

keyColumn has the advantage of reducing the number of renders your component has to perform while also making it much easier to write.