Reputation: 4173
Codesandbox example: https://codesandbox.io/s/react-table-state-not-updating-hmquq?file=/src/App.js
I am using the react-table package (version 7.1.0).
I have a table which displays some invoices like so:
The user should be able to select some or all of these items using the selected
checkbox.
The selected
field is not part of the data. However, when the user hits a selected
checkbox, the field should toggle and an array storing document numbers should be populated.
To store the document numbers, I have a stateful getter and setter:
const [selectedInvoiceIds, setSelectedInvoiceIds] = useState([]);
To populate the field, I am attempting to simply add the document number to the array immutably, from the onChange
of the checkbox:
{
Header: "Selected",
accessor: "selected",
Cell: item => {
const { documentNumber } = item.row.values;
return (
<input
type="checkbox"
checked={selectedInvoiceIds.includes(documentNumber)}
onChange={() => {
setSelectedInvoiceIds([...selectedInvoiceIds, documentNumber]);
}}
/>
);
}
}
When a checkbox is clicked for the first time, the selectedInvoiceIds
becomes populated:
selectedInvoiceIds: ["706942"]
The problems are:
checked={selectedInvoiceIds.includes(documentNumber)}
selectedInvoiceIds
value gets overwritten when another document number is added, instead of being added to, as if the state is re-initialising to []
somewhere in between.Can it be explained why these state issues are occurring and how to get around it?
I am aware of the useTableState
value exposed by react-table, but I don't know how I can apply it to this use case.
Codesandbox example: https://codesandbox.io/s/react-table-state-not-updating-hmquq?file=/src/App.js
Upvotes: 0
Views: 5126
Reputation: 3032
Because of useMemo, add your array to last parameter
const columns = React.useMemo(
// ....
,
[selectedInvoiceIds]
);
And as we need toggle checkboxed it is more reasonable to keep selected ids in object instead of array and update it as this
setSelectedInvoices({
...selectedInovicesIds,
documentNumber: !selectedInovicesIds[documentNumber]}
)
so it will toggle mark
Upvotes: 1
Reputation: 8024
There are multiple issues in this code:
// 1) updates to state should should use callback function if it uses prv state
return (
<input
type="checkbox"
checked={selectedInvoiceIds.includes(documentNumber)}
onChange={() => {
setSelectedInvoiceIds(prvSelectedInovicesId => [...prvSelectedInovicesId, documentNumber]);
}}
/>
);
// 2) also columns is using useMemo, however not providing dependencies, so columns are not being updated when the selectedInvociesIds state gets updated
// 3) you are not yet handling the toggle, this mean you are just always just adding to the array and not removing from it
here is a working version code sandbox https://codesandbox.io/s/react-table-state-not-updating-wkri3?file=/src/App.js
Upvotes: 2