lundi 7 septembre 2020

OnChange function does not allow checkbox to update its state

I have made my own Checkbox component, so that I can handle its checked state easier:

export default function Checkbox({ name, handleOnChange, defaultState }) {
  const [checked, setChecked] = useState(defaultState || false);

  useEffect(() => {
    defaultState || setChecked(false);
  }, [name]);

  function handleCheckedStateOnChange() {
    setChecked((prevState) => {
      console.log(name);
      console.log("prevstate: ", prevState);
      console.log("newstate: ", !prevState);
      return !prevState;
    });
  }

  return (
    <input
      onChange={(e) => {
        e.persist();
        handleCheckedStateOnChange();
        handleOnChange(e);
      }}
      checked={checked}
      type={"checkbox"}
      name={`${name}`}
    />
  );
}

And it works fine.. sometimes.

I have two instances of that Checkbox and both of them used to work, however I have no idea what has changed and why one of them stopped working, as I have not touched the code responsible for that at all, its like, it worked last night and now all of the sudden it stopped, or at least I don't remember doing anything...

Anyway, here are the two checkboxes:

This one is a single checkbox and it works just fine.

<Checkbox
  name={robotToAdd.name}
  handleOnChange={handleCanChangeConfigOnChange}
/>

Here is its handleOnChange function, which simply changes the canChangeConfig property of the object to true/false depending on wether its checked or not:

function handleCanChangeConfigOnChange(e) {
  setRobotToAdd((prevRobot) => {
    return {
      ...prevRobot,
      canChangeConfig: e.target.checked,
    };
  });
}

The second instance is within a map function that renders a couple of these checkboxes:

selectedRobot.Configs.map((config) => (
  <React.Fragment key={`${robotToAdd.Name}-${config}`}>
    <label htmlFor={`${robotToAdd.Name}-${config}`}>{config}</label>
    <Checkbox
      name={`${robotToAdd.name}-${config}`}
      handleOnChange={handleSelectConfigOnChange}
    />
  </React.Fragment>)
)

And here is its handleOnChange function, what it does is simply adding the checked config to the array of configs of the robot:

function handleSelectConfigOnChange(e) {
  const robotToAddCopy = { ...robotToAdd };
  const config = e.target.name.substring(e.target.name.indexOf("-") + 1);

  const onCheckedAddConfigIfMissing = (config) => {
    !robotToAddCopy.allowedUIs.includes(config) &&
      robotToAddCopy.allowedUIs.push(config);
  };

  const onUncheckedRemoveConfigIfAdded = (config) => {
    robotToAddCopy.allowedUIs.splice(
      robotToAddCopy.allowedUIs.indexOf(config),
      1
    );
  };

  e.target.checked
    ? onCheckedAddConfigIfMissing(config)
    : onUncheckedRemoveConfigIfAdded(config);

  setRobotToAdd(robotToAddCopy);  // this for some reason seems to be preventing the checkbox from changing its state
}

The config does get added to the robot, but the checkbox does not get its checked state set to true. If I remove the handleOnChange(e) from the onChange of the input element all checkboxes are working and getting checked and unchecked.

If I leave the handleOnChange(e) only the first checkbox works and the console logs within the setChecked function do show the correct states that must be set, however they simply do not and the state of all checkboxes after the first is always false.

ALSO, I have another page for editing a robot where I am using the exact same code there and the checkboxes there work, they are again being mapped from an array of configs and I am using the exact same onChange function, with the only difference that the last function is called setRobotToEdit(robotToEditCopy), but its absolutely the same code inside it. I have also tried adding a key to the that did not help either.




Aucun commentaire:

Enregistrer un commentaire