Using react-table 7, my cell re-renders and loses focus on every change. I have it bound two ways to a property in its parent component. Inputting in the cell updates the data source that I'm using to populate the table, so it re-renders the table.
The official docs get around it in a pretty complicated way: The cell receives an updateMyData function which is passed to the table, the cell is defined with its own state so that onChange updates the cell's internal state, and onBlur runs the updateMyData function. This solution doesn't really work with how my project is structured, and with how I plan to re-use components.
Ideally I'd like to continue with the two-way binding approach that I have, but I'm out of ideas. The table data is already memoized but since it does change, it re-renders the table and I lose focus.
Here is my very simple cell definition:
tempTable["defaultColumn"] = {
Cell: ({value, row, column}) => {
// TODO: fix this so that inputting doesn't render a new component, otherwise I lose focus on every change.
return <input
key={`Cell_${row}_${column}`}
type="number"
value={value}
onChange={(e) => updateData(e, column, row)} />
}
}
My updateData function called onChange:
const updateData = useCallback(
(event, column, row) => {
props.onProductTableChange(event, column, row);
}, [props]
);
and the onProductTableChange function defined in my parent component
// handles changes to the events products table
const handleProductTableChange = useCallback(
(event, column, row) => {
// get the event products in a new array
let newEventProducts = [...eventProducts];
// let the value be the value of the event target
let value = event.target.value
// if the column we're updating is name, manually format some of the data differently...
if (column.id === "Name") {
value = parseInt(event.target.value);
newEventProducts[row.index].Id = value;
// ... and manually get the new name, since we only updated the id
const allProducts = [...ddvProducts];
newEventProducts[row.index].Name = allProducts.filter(prod => prod.id === value)[0]["name"];
} else {
// else just set the column.id ("SalePrice", "QuantityAllocated", etc) to the new value
newEventProducts[row.index][column.id] = value;
}
setEventProducts(newEventProducts);
console.log(newEventProducts);
},
[setEventProducts, ddvProducts, eventProducts]
);
Thanks in advance, I'd love to know if what I'm trying to do is even possible.