Darkbound
Darkbound

Reputation: 3434

Checkbox is not resetting itself on a re-render

I have a select drop down menu, and once an item is selected, a checkbox shows up, my problem is that if for example, I select "Robot1" and I check its checkbox, but then I decide to select "Robot2", when I do that the checkbox stays checked. I have tried added a state just for the checkbox (althought I dont think thats necessary, since the setSelectedRobot gets triggered and that triggers a re-render anyway...?!), I have also tried using the checked prop and the defaultChecked prop, but I could not get the checkbox to reset itself when a different option is selected.

const robotToAdd = { 
                     name: "", someBoolean: false 
                   }
const robots = [
                 {name: "Robot1", someBoolean: false},
                 {name: "Robot2", someBoolean: false},
                 {name: "Robot3", someBoolean: false},
                 {name: "Robot4", someBoolean: false}
               ]

function Component() {
  const [selectedRobot, setSelectedRobot] = useState({});
  const [checked, setChecked] = useState(false);

  return (
    <>
      <select onChange={(e) => { 
          const robot = robots.find(robot => robot.name === e.target.value);
          setSelectedRobot(robot)
      >
        <option>Choose a robot:</option>
        {robots.map(robot => 
           <option key={robot.name} value={robot.name}>{robot.name}</option>
        )} 
      </select>

      {Object.keys(selectedRobot).length > 0 && (
        <input checked={checked} 
               type="checkbox" 
               onChange={(e) => {
                 robotToAdd.someBoolean = e.target.checked
                 setChecked(e.target.checked)
               }
        />)
    </>
  )
}

Upvotes: 1

Views: 1084

Answers (2)

Drew Reese
Drew Reese

Reputation: 203051

Simply add a react key to the input that changes when a new robot is selected. When the key changes then react will mount a new element.

function MyComponent() {
  const [selectedRobot, setSelectedRobot] = useState({});

  return (
    <>
      <select
        onChange={(e) => {
          const robot = robots.find((robot) => robot.name === e.target.value);
          setSelectedRobot(robot);
        }}
      >
        <option>Choose a robot:</option>
        {robots.map((robot) => (
          <option key={robot.name} value={robot.name}>
            {robot.name}
          </option>
        ))}
      </select>

      {Object.keys(selectedRobot).length > 0 && (
        <input
          key={selectedRobot.name} // <-- use robot name as key
          type="checkbox"
        />
      )}
    </>
  );
}

Edit checkbox-is-not-resetting-itself-on-a-re-render

If you wanted to keep the checked state then simply reset the checked state back to false when a new robot is selected.

<select
  onChange={(e) => {
    const robot = robots.find((robot) => robot.name === e.target.value);
    setSelectedRobot(robot);
    setChecked(false);
  }}
>

Upvotes: 2

Kenny John Jacob
Kenny John Jacob

Reputation: 1198

You can try this, remove the checked state. On the checkbox, when the event occurs, you take the current selectedRobot and set its someBoolean field value.

function Component() {
  const [selectedRobot, setSelectedRobot] = useState({});

  return (
    <>
      <select onChange={(e) => { 
          const robot = robots.find(robot => robot.name === e.target.value);
          setSelectedRobot(robot)
      >
        <option>Choose a robot:</option>
        {robots.map(robot => 
           <option key={robot.name} value={robot.name}>{robot.name}</option>
        )} 
      </select>

      {Object.keys(selectedRobot).length > 0 && (
        <input checked={selectedRobot ? selectedRobot.someBoolean : false} 
               type="checkbox" 
               onChange={(e) => {
                 setSelectedRobot(robot => ({...robot, someBoolean: e.target.checked}))
               }
        />)
    </>
  )
}

Upvotes: 0

Related Questions