Idea of handling data changes
- A user changes the value of a cell. Among others, it could mean that the user has:
- typed a new value into a cell by cell editor,
- used a fill handle ,
- pasted some data into the cell matrix,
- interacted with a clickable cell (e. g. expanded group cell).
- ReactGrid fires the
onCellsChanged
event - Your handler function processes the event and updates the application state
- The
ReactGrid
component receives new data and gets rerendered
By default, the data grid will behave as if it was in a "read-only" mode.
To support dynamic data editing, you will have to handle the onCellsChanged
event yourself.
When my handler function is called?
- Changes have been committed after cell editing.
- After pasting with the shortcut or the context menu.
- After fill handle action.
Sample change handler function
We can declare a basic handler function like this:
const handleChanges = (changes: CellChange[]) => {
setRows((prevRows) => {
changes.forEach(change => {
const changeRowIdx = prevRows.findIndex(el => el.rowId === change.rowId);
const changeColumnIdx = columns.findIndex(el => el.columnId === change.columnId);
prevRows[changeRowIdx].cells[changeColumnIdx] = change.newCell;
});
return [...prevRows];
});
};
The function receives an array describing all of the changes made to the data grid's cells. Given that information, we find the row and the column affected by each change, and then replace an appropriate cell object with a new one.
Let's pass the handler function to our ReactGrid component:
return (
<ReactGrid
rows={rows}
columns={columns}
onCellsChanged={handleChanges} // highlight-line
/>
)
Live demo
And here's an interactive demo showing the event handler in action. Notice how it is now possible to edit the data not only by typing new values into the cells, but also by using the fill handle (only PRO) or by pasting data from the clipboard.
Code
const App = () => { const [columns] = React.useState<Column[]>(() => [ { columnId: "Name", width: 100 }, { columnId: "Surname", width: 100 } ]); const [rows, setRows] = React.useState<Row[]>(() => [ { rowId: 0, cells: [ { type: "header", text: "Name" }, { type: "header", text: "Surname" } ] }, { rowId: 1, cells: [ { type: "text", text: "Thomas" }, { type: "text", text: "Goldman" } ] }, { rowId: 2, cells: [ { type: "text", text: "Susie" }, { type: "text", text: "Spencer" } ] }, { rowId: 3, cells: [ { type: "text", text: "" }, { type: "text", text: "" } ] } ]); const handleChanges = (changes: CellChange[]) => { setRows((prevRows) => { changes.forEach(change => { const changeRowIdx = prevRows.findIndex(el => el.rowId === change.rowId); const changeColumnIdx = columns.findIndex(el => el.columnId === change.columnId); prevRows[changeRowIdx].cells[changeColumnIdx] = change.newCell; }); return [...prevRows]; }); }; return ( <ReactGrid rows={rows} columns={columns} onCellsChanged={handleChanges} /> ); } render(<App/>)
Preview