'react table select rows - programmatically select rows based on input props

I have created a react table with select rows following this example. I'm trying to modify it so that when the data loads, the corresponding checkbox is either checked or unchecked based on the row data's included value. The value doesn't seem to be recognized and when I check/uncheck a row the onChange console.log event isn't being fired. What am I doing wrong.

Heres my Sandbox Example

DATA

[
  {
    systemId: 13,
    deqId: "25007",
    facilityId: 6487,
    sourceId: "WS002",
    sourceName: "GROVE SPRING",
    flowRate: 461,
    flowUom: "GPM   ",
    included: true
  },
  {
    systemId: 13,
    deqId: "25007",
    facilityId: 4742,
    sourceId: "WS004",
    sourceName: "WELL #1",
    flowRate: 1100,
    flowUom: "GPM   ",
    included: true
  },
  {
    systemId: 13,
    deqId: "25007",
    facilityId: 4743,
    sourceId: "WS005",
    sourceName: "100 W (WELL #2)                         ",
    flowRate: 800,
    flowUom: "GPM   ",
    included: true
  },
  {
    systemId: 13,
    deqId: "25007",
    facilityId: 4744,
    sourceId: "WS007",
    sourceName: "NORTH (WELL #3)                         ",
    flowRate: 900,
    flowUom: "GPM   ",
    included: true
  }
];

INDETERMINATE CHECKBOX

const IndeterminateCheckbox = React.forwardRef(
  ({ indeterminate, checked, name, ...rest }, ref) => {
    const defaultRef = React.useRef(checked);
    const resolvedRef = ref || defaultRef;

    React.useEffect(() => {
      resolvedRef.current.indeterminate = indeterminate;
      resolvedRef.current.checked = checked;
    }, [resolvedRef, indeterminate, checked]);

    return (
      <>
        <input
          type="checkbox"
          ref={resolvedRef}
          checked={checked}
          name={name}
          id={name}
          {...rest}
        />
      </>
    );
  }
);

REACT TABLE


function ReactTable({
  columns,
  data,
  handleCheckboxSelection,
  handleCheckboxStateChange
}) {
  // Use the state and functions returned from useTable to build your UI
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    footerGroups,
    rows,
    prepareRow,
    selectedFlatRows
  } = useTable(
    {
      columns,
      data
    },
    useRowSelect,
    (hooks) => {
      hooks.visibleColumns.push((columns) => [
        // Let's make a column for selection
        {
          id: "selection",
          // The header can use the table's getToggleAllRowsSelectedProps method
          // to render a checkbox
          Header: (
            { getToggleAllRowsSelectedProps },
            handleCheckboxStateChange
          ) => (
            <div>
              <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
            </div>
          ),
          // The cell can use the individual row's getToggleRowSelectedProps method
          // to the render a checkbox
          Cell: ({ row }) => (
            <div>
              <IndeterminateCheckbox
                name={row.original.sourceId}
                onChange={(row) => console.log(row.original)} //not firing
                checked={row.original.included}
                {...row.getToggleRowSelectedProps()}
              />
            </div>
          )
        },
        ...columns
      ]);
    }
  );

  // Render the UI for your table
  return (
    <>
      <table {...getTableProps()}>
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th {...column.getHeaderProps()}>{column.render("Header")}</th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {rows.slice(0, 10).map((row, i) => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map((cell) => {
                  return (
                    <td {...cell.getCellProps()}>{cell.render("Cell")}</td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
        <tfoot>
          {footerGroups.map((group) => (
            <tr {...group.getFooterGroupProps()}>
              {group.headers.map((column) => (
                <td {...column.getFooterProps()}>
                  <b>{column.render("Footer")}</b>
                </td>
              ))}
            </tr>
          ))}
        </tfoot>
      </table>
      <button onClick={() => handleCheckboxSelection(selectedFlatRows)}>
        Save
      </button>
    </>
  );
}

TABLE IMPLEMENTATION

const MyDataTable = ({
  data
}) => {

const handleCheckboxSelection = (array) => {
    console.log(array.map((d) => d.original));
  };

  const columns = React.useMemo(
    () => [
      {
        Header: "Source ID",
        accessor: "sourceId"
      },
      {
        Header: "Source Name",
        accessor: "sourceName"
      },
      {
        Header: "Flow Rate (GPM)",
        accessor: (d) => {
          return d.flowRate ? numberWithCommas(d.flowRate) : "";
        }
      }
    ],
    []
  );
  return (
    <ReactTable
      columns={columns}
      data={data}
      handleCheckboxSelection={handleCheckboxSelection}
    />
  );
};


Solution 1:[1]

The props you added to IndeterminateCheckbox are being overwritten. row.getToggleRowSelectedProps() returns an object:

{
   onChange: function,
   checked: Boolean,
   title: String,
   indeterminate: Boolean,
   style: Object
}

which overwrites your properties.

The correct way to do what you want to do would be to use initialState.selectedRowIds property from the useRowSelect API.

Map your data to their included values, then add that array to the initialState as selectedRowIds. In ReactTable.js:

const selectedRowIds = data.map((d, ind) => d.included)
const { 
  // etc 
} = useTable(
  {
    columns,
    data,
    initialState: {selectedRowIds}
  },
  //etc
  ...columns
  }
);

Solution 2:[2]

you have to refresh your Table.
you can use useState.
example : you can add onClick={this.mychange} to your save Button.

mychange = async () => {
  
    this.setState({
        List: //the new List Data
    })
    
  }

and dont forget the Constructor.

constructor() {
    super();
    this.state = {
      List: anyList,
    };
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Peter Csala