alanbuchanan
alanbuchanan

Reputation: 4173

React-table: State doesn't change as expected, and table doesn't update

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:

table example

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)}

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

Answers (2)

Dmitry Reutov
Dmitry Reutov

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

ehab
ehab

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

Related Questions