React (Reakit): How to ask for confirmation, when toggling a checkbox?

2.3k Views Asked by At

I'm wondering, if there's a way to ask for confirmation with Reakit's checkbox. I'm using Reakit, since I found a quick way to get it to read database's boolean information, but I welcome other methods too!

I'm used to doing confirmations with buttons with async and window.confirm:

<button onClick={async hiStackOverflow => {
  if (window.confirm("Want to do this?")) {
    // saving to database here 
  }
}}>

But I didn't figure out how to do it with a checkbox. In short, I want for the page to confirm (and then save to database), when the user toggles on/off the checkbox.

// personData = database table, with boolean "recurring"
// row = which entity in a table we are talking about

function CheckboxThing ({ row, personData }) {

  const checkbox = useCheckboxState({state: personData[row].recurring});

  return (
    <div className="checkbox-admin-other">
      <Checkbox 
        {...checkbox} 
        // what here?? onClick or something?
      />
    </div>
  );
}
3

There are 3 best solutions below

2
On BEST ANSWER

After coding around a little while, I found the solution! It turns out, you can put async inside Reakit Checkbox. Thanks to Tomislav and Diego, their answers helped me try different things and get it clean!

Here's the full function:

// admin can edit the right to join back to the queue after getting to the front
function RecurringBox ({ row, personData }) {

  // sets the original values
  const checkbox = useCheckboxState({state: personData[row - 1].recurring});

  return (
    <Checkbox {...checkbox} onChange={async checkboxSwitch => {
      if (window.confirm("Change it?")) {

        checkboxSwitch.persist();

        // saving it to the database
        await put(`${process.env.API_PATH}/person`,
          {
            "id": personData[row - 1].id,
            "name": personData[row - 1].name,
            "recurring": checkboxSwitch.target.checked
          });
        reload(`${process.env.API_PATH}/person`);

      } else {
        return null;
      }
    }}/>
  );
}
0
On

You can "observe" changes on checkbox.state using React Hooks:

function CheckboxThing({ row, personData }) {
  const checkbox = useCheckboxState({ state: personData[row].recurring });

  React.useEffect(() => {
    // checking if state has changed
    if (checkbox.state !== personData[row].recurring) {
      if (window.confirm("Want to do this?")) {
        // saving to database here
      } else {
        // revert checkbox state otherwise
        checkbox.setState(!checkbox.state);
      }
    }
  }, [checkbox.state, checkbox.setState, personData[row].recurring]);

  return (
    <div className="checkbox-admin-other">
      <Checkbox {...checkbox} />
    </div>
  );
}

With React.useEffect, the user will see the checkbox checked before window.confirm opens. But you can use React.useLayoutEffect instead if you want it to open before checkbox state changes on the UI.

5
On

Reakit's checkbox can be used like this:

const toggle = () => setChecked(!checked);
return <Checkbox checked={checked} onChange={toggle} />;

This means that the checkbox will be checked if the variable 'checked', which needs to be put in the state of your React component, is true and that the method called 'toggle' will be called when the user toggles the checkbox. In that method, you can put the code which will show the Confirmation Prompt and then change checked if user clicked 'Yes' or leave it as it is if they check 'No'.