grouped-checkboxes icon indicating copy to clipboard operation
grouped-checkboxes copied to clipboard

Infinite re-rendering when trying to update a state with CheckboxGroup

Open seyade opened this issue 5 years ago • 4 comments

Hi @AlexLisenkov

It's me again.

When I want to update a state through the onChange props of CheckboxGroup, it's re-renders forever. The infinite re-rendering starts on page load, not waiting for a change event to happen first. It only does that for state update whether I'm using this.setState() or useState. I think there is an issue between the CheckboxGroup and updating a state, or with react-table.

How can I stop the infinite re-rendering, please?

import React, { useState } from 'react;
import ReactTable, { ReactTableDefaults } from 'react-table';

function Table(props) {
  const [role, setRole] = useState({
      name: '',
      permissions: [],
      checked: false,
  });

  const data = [{ name: "Uzumaki" }, { name: "Goku" }];
  const actionHeaders = [{ name: "ADD" }, { name: "DELETE" }];

  const columns = [
    {
      Header: "Name",
      accessor: "name",
      Cell: row => {
        return (
          <span>
            <AllCheckerCheckbox />
            Select all
          </span>
        );
      }
    },
    ...renderActionColumns()
  ];

  const onCheckAll = checkboxes => {
    console.log("AllCheckboxes", checkboxes);
    
    // For some reason, this triggers an infinite re-rendering when the handler is on CheckboxGroup!
    setRole({
      ...role,
      permissions: checkboxes
    });
  };

  function renderActionColumns() {
    return actionHeaders.map(action => {
      return {
        Header: action.name,
        Cell: row => {
          return (
            <Checkbox />
          );
        }
      };
    });
  }

  // Where the issue starts.
  function TRComponent({ children, ...rest }) {
    return (
      <div className="rt-tr" role="row">
        <CheckboxGroup onChange={onCheckAll}>
          <span>{children}</span>
        </CheckboxGroup>
      </div>
    );
  }

  Object.assign(ReactTableDefaults, {
    TrComponent: TRComponent
  });

  return (
    <ReactTable data={data} columns={columns} />
  );
}

export default Table;

seyade avatar May 27 '20 23:05 seyade

Hi @AlexLisenkov

How can I fork this so I can maybe fix it in my project?

seyade avatar Jun 02 '20 09:06 seyade

You can fork by clicking on the fork button on the top right.

AlexLisenkov avatar Jun 02 '20 09:06 AlexLisenkov

Sorry I was asking this because some forking might require credentials, etc. And didn't wanna go through all that.

Thanks though!

seyade avatar Jun 02 '20 09:06 seyade

Hi @seyade I had the same issue. But a workaround I did was to not update via react state. e.g

import { AllCheckerCheckbox, Checkbox, CheckboxGroup } from '@createnl/grouped-checkboxes';

let  checkedItems;

const MyGroupedCheckboxes = ({ data }) => {
        const onCheckboxChange = (checkboxes) => {
            //  get all values fields in checkboxes where checked is true into an array
            const checkedValues = _.filter(checkboxes, { checked: true }).map(item => item.value);
            if (checkedValues.length > 0) {
                checkedItems = checkedValues;
            }
        }

        return (
            // @ts-ignore
            <CheckboxGroup onChange={onCheckboxChange}>
                <label>
                    <AllCheckerCheckbox />
                    SELECT ALL
                </label>
                {/* other checkboxes  here*/}
                ))}
            </CheckboxGroup>
        );
    };

You can then use checkedTables variable on your page.

abbeyseto avatar May 26 '22 09:05 abbeyseto