react-table-plugins
react-table-plugins copied to clipboard
useCellRangeSelection fails with virtualization
Hey,
First of all, this is a great hook! Thanks for providing it - all the appreciation for your work.
I tried the useCellRangeSelection with virtualization, I have enabled in my POC project both: react-window and react-virtual, but for both of them the hook is failing.
Error details:
Error: React Table: startCellId and endCellId has to be valid cell Id
Code path:
// Returns all cells between Range ( between startcell and endcell Ids)
const getCellsBetweenId = React.useCallback(
(startCell, endCell) => {
if (!cellsById[startCell] || !cellsById[endCell]) {
console.info({ startCell, endCell })
throw new Error(
React Table: startCellId and endCellId has to be valid cell Id
)
}
I was expecting the cells to be used from the object that's still in memory and not from the rendering objects that are dropped. But since I am new to these hooks I might miss something.
Thanks again.
Glad, anyone asked about it, so one of the reason for this can be cell ids are assigned in prepareRow
which when virtualizing can skip for some rows but in getCellsBetweenId
they are required. To fix this, cell id dependency has to be removed from getCellsBetweenId
with some other logic, i will have a look at this..
Thank you, Rohit. I will keep following if there is any update on this; and I can take a deeper look into the code and we can discuss solutions over the weekend. Glad to see your quick response. Also, sorry for opening a duplicate issue. GitHub did a timeout on first, but it looks that it opened it.
Hello, sorry to reopen the topic. I'm trying to use the plugin as well and I'm having trouble. The problem comes from the cellsById instance which when initializing the table is empty. Have you encountered this problem? Can you help me ?
Just if this is still on the table. If you need useRangeSelection to work with virtualization, here is the code.
Just replace getCellsBetweenId with this function. Kudos to @gargroh for prompt on removing cellsById dependency
const getCellsBetweenId = React.useCallback(
(startCell: string, endCell: string) => {
const updatedRows = rows.map((el, idx) => ({ ...el, index: idx }));
const startCellPosition = updatedRows.findIndex((el) => startCell.includes(el.id));
const endCellPosition = updatedRows.findIndex((el) => endCell.includes(el.id));
if (startCellPosition === -1 || endCellPosition === -1) {
throw new Error(`React Table: startCellId and endCellId has to be valid cell Id`);
}
const rowsIndex = [startCellPosition, endCellPosition];
const columnsIndex: number[] = [];
allColumns.forEach((col, index) => {
if (startCell.includes(col.id)) {
columnsIndex.push(index);
}
});
const selectedColumns = [];
const selectedRows = [];
for (let i = Math.min(...columnsIndex); i <= Math.max(...columnsIndex); i++) {
selectedColumns.push(allColumns[i].id);
}
for (let i = 0; i <= updatedRows.length - 1; i++) {
if (updatedRows[i].index >= Math.min(...rowsIndex) && updatedRows[i].index <= Math.max(...rowsIndex)) {
selectedRows.push(updatedRows[i].id);
}
if (updatedRows[i].index === Math.max(...rowsIndex)) break;
}
const cellsBetween: { [keys: string]: boolean } = {};
if (selectedRows.length && selectedColumns.length) {
for (const item of selectedRows) {
for (const item1 of selectedColumns) {
const id = item1 + cellIdSplitBy + item;
cellsBetween[id] = true;
}
}
}
return cellsBetween;
},
[allColumns, cellIdSplitBy, rows],
);