Static vs dynamic
Static by default
By default <DataSheetGrid />
is static, meaning that it saves the props it receives
on the first render and never updates them. This is extremely useful to avoid
un-necessary re-renders due to inline props change:
import { DataSheetGrid } from 'react-datasheet-grid'
const MyComponent = () => {
const [ data, setData ] = useState([])
return (
<DataSheetGrid
value={data}
onChange={setData}
columns={[ // <- ⚠️ A new array is passed on every render
{/*...*/},
{/*...*/},
{/*...*/},
]}
createRow={() => ({ id: genId() })} // <- ⚠️ A new function is passed on every render
/>
)
}
Inline props are the easiest way to write your component, and this example is perfectly fine because even tho
<DataSheetGrid />
receives different props every time, this does not trigger a re-render of the grid because it "saved"
the value it received on original render.
Which props are static?
All props that are not primitive (ie. objects, array, or functions) are static.
Therefore, columns
, createRow
, duplicateRow
and other non primitive typed props are static and cannot be changed
after first render.
The only exception to this rule is the onChange
prop that is always dynamic.
All other primitive props (number, string, or boolean) are dynamic. Therefore, data
, height
, lockRows
and other
primitive typed props can be changed after first render.
When to opt out of the static behavior?
A good rule of thumb is to keep using the static version of <DataSheetGrid />
until it does not work as intended.
This happens when:
- You have dynamic columns. Meaning that columns can be added / removed, or their props can change after the first render
- Some functions like
duplicateRow
orcreateRow
must change after the first render
Dynamic version
To opt out of the static version, simply use <DynamicDataSheetGrid />
instead:
import { DynamicDataSheetGrid } from 'react-datasheet-grid'
const MyComponent = () => {
const [ data, setData ] = useState([])
const columns = useMemo(() => [
{/*...*/},
{/*...*/},
{/*...*/},
], [])
const createRow = useCallback(() => ({ id: genId() }), [])
return (
<DynamicDataSheetGrid
value={data}
onChange={setData}
columns={columns}
createRow={createRow}
/>
)
}
When you decide to use <DynamicDataSheetGrid />
you can no longer inline the props and have to use
useMemo
and useCallback
for all props that are either a function or an object.
This allows you to have dynamic props while still having optimal performance.