Adam
Adam

Reputation: 677

Checkbox not toggling in React with Material-UI

So I have a React code in which the checkbox is not toggling when I click on it.

This is the codesandbox link: https://codesandbox.io/s/inspiring-kirch-q6p4h

I am initializing the checkbox state like this:

const [checkbox, setCheckBox] = useState(() => {
    let checkboxObj = {};

    rows.forEach((e) => {
      checkboxObj[e.id] = false;
    });
    return checkboxObj;
  });

We have a column array in which there is a function called customElement which contains the checkbox handler.

const columns = [
    {
      key: "Source_campname",
      title: "TS Camp Name",
      customElement: function (row) {
        console.log(checkbox);
        return (
          <FormControlLabel
            control={
              <Checkbox
                checked={checkbox[row.id]}
                key={row.id}
                onChange={() =>
                  handleChange(row.Source_campname, row.id, checkbox)
                }
                name={row.id}
              />
            }
            label={[row.Source_campname]}
          />
        );
      }
    },
    {
      key: "Tracker_campname",
      title: "TR Camp Name"
    }
  ];

Checkbox toggle is handled in the function below:

const handleChange = (name, campid) => {
    setCheckBox({ ...checkbox, [campid]: !checkbox[campid] });
  };

What is happening is that the checkbox is not toggling when I click on it. Any idea what is going on?

Upvotes: 2

Views: 116

Answers (2)

prasanth
prasanth

Reputation: 22510

Don't use the callback inside the useState declaration

Example Codesanbox

const [checkbox, setCheckBox] = useState({});

Upvotes: 1

Drew Reese
Drew Reese

Reputation: 203466

I dug in on this a bit and after converting handleChange to use a functional state update

const handleChange = (name, campid) => {
  setCheckBox((checkbox) => ({
    ...checkbox,
    [campid]: !checkbox[campid]
  }));
};

to try and avoid any stale enclosures with the columns prop passed to ThanosTable I dug in on that component code to see if/how it handled re-enclosed checkbox values passed in the columns prop.

Issue

The columns are stored in local state in the visibleColumns state and never again does ThanosTable look at and respond to changes on the columns prop.

Solution

Add an useEffect to update the visibleColumns state when props update.

useEffect(() => {
  setVisibleColumns(
    !options.removeColumnsFeature &&
    options.showColumns &&
    options.showColumns.length
    ? [...columns.filter((x) => options.showColumns.includes(x.key))]
    : [...columns]
  )
}, [columns, options]);

Edit checkbox-not-toggling-in-react-with-material-ui

You can, and should, factor the common logic between the visibleColumns state initializer and effect callback.

Upvotes: 2

Related Questions