Data Grid - Row updates
Always keep your rows up to date.
The rows prop
The simplest way to update the rows is to provide the new rows using the rows prop.
It replaces the previous values. This approach has some drawbacks:
- You need to provide all the rows.
- You might create a performance bottleneck when preparing the rows array to provide to the Data Grid.
The updateRows() method
If you want to only update part of the rows, you can use the apiRef.current.updateRows() method.
The default behavior of updateRows() API is to upsert rows.
So if a row has an id that is not in the current list of rows then it will be added to the Data Grid.
Alternatively, if you would like to delete a row, you would need to pass an extra _action property in the update object as below.
apiRef.current.updateRows([{ id: 1, _action: 'delete' }]);
Replacing a row instead of merging it
By default, updateRows() merges each update into the existing row, which produces a new object.
Pass a { _action: 'replace', row } update to store the given object as the row instead of merging it.
apiRef.current.updateRows([{ _action: 'replace', row }]);
The Data Grid stores row by reference, so apiRef.current.getRow(id) returns the very object you passed in, with its prototype chain and its #private fields intact.
Use this when the row is a class instance whose identity or private state must survive the update.
Any field missing from the replacement is removed from the row, because a replace is never a merge.
Provide a replacement that is a different object from the one currently stored. The Data Grid and its memoized rows rely on reference changes to re-render, so replacing a row with the same, mutated instance may not repaint that row.
When a single updateRows() call contains several updates for the same row, make the replace the last one for that row.
The updates that follow it are merged onto the replacement, which keeps its prototype but is no longer the same object and no longer carries its #private fields, because a merge can't copy them.
The same update can be returned from processRowUpdate().
See Editing persistence—Replacing the row instead of merging it for details.
Infinite loading
The grid provides a onRowsScrollEnd prop that can be used to load additional rows when the scroll reaches the bottom of the viewport area.
In addition, the area in which onRowsScrollEnd is called can be changed using scrollEndThreshold.
Lazy loading
Lazy Loading works like a pagination system, but instead of loading new rows based on pages, it loads them based on the viewport. It loads new rows in chunks, as the user scrolls through the Data Grid and reveals empty rows.
The Data Grid builds the vertical scroll as if all the rows are already there, and displays empty (skeleton) rows while loading the data. Only rows that are displayed get fetched.
To enable lazy loading, there are a few steps you need to follow:
First, set rowsLoadingMode="server".
Then, set rowCount to reflect the number of available rows on the server.
Third, set a callback function on onFetchRows to load the data corresponding to the row indices passed within GridFetchRowsParams.
Finally, replace the empty rows with the newly fetched ones using apiRef.current.unstable_replaceRows() like in the demo below.
High frequency
Whenever the rows are updated, the Data Grid has to apply sorting and filters.
This can be a problem if you have high-frequency updates.
To maintain good performance, the Data Grid lets you batch the updates and only apply them after a period of time.
You can use the throttleRowsMs prop to define the frequency (in milliseconds) at which rows updates are applied.
When receiving updates more frequently than this threshold, the Data Grid will wait before updating the rows.
The following demo updates the rows every 10 ms, but they are only applied every 2 seconds.