robeert
robeert

Reputation: 95

react checkbox doesn't reset without random key?

Hello i have a checkbox component that looks like this

export default function Checcky({
  lab,
  checcky,
  name,
  className = "",
  onChange,
}) {
  return (
    <div className={"checkky relative flex center-flex " + className}>
      <label htmlFor={name} className="labelin mr-4">
        {lab}
      </label>
      <input
        id={name}
        name={name}
        type="checkbox"
        defaultChecked={checcky}
        onChange={onChange}
        className=" absolute center-absolute"
      />
      <label htmlFor={name} className="slider relative cursor-p"></label>
    </div>
  );
}

And i use it like this

       <Checcky
            lab="Admin"
            name="admin"
            key={ Math.random() }
            onChange={handleChange}
            checcky={values.admin}
            className="justify-start my-4"
        />

I've noticed that if i don't put the key={Math.random()} when i "reset" the state to his original value the input doesn't get "checked back" this is my usual scenario

const [values,setValues] = useState({admin:false})
const handleChange = (e) =>{
  let v = values[e.target.name];
  v = e.target.checked;
  setValues({...values,[e.target.name] : v})
}

however if i do maybe a fetch and after the result i want to reset the state like this

const postData = async () =>{
  await fetch(somerandomurl)
  setValues({...values,admin:false})
}

the input doesnt get unchecked it remains checked even if the state has changed unless i put this key={Math.random()} and i know it works because since the key changes the components gets re rendered but is there a way to do it without this workaround?

Upvotes: 0

Views: 157

Answers (1)

Ramesh Reddy
Ramesh Reddy

Reputation: 10662

Try these:

use checked instead of defaultChecked:

<input
  id={name}
  name={name}
  type="checkbox"
  checked={checcky}
  onChange={onChange}
  className=" absolute center-absolute"
/>

use functional state updates as your new state depends on old state:

const handleChange = (e) => {
  const { name, checked } = e.target;
  setValues(prevValues => ({...prevValues, [name]: checked }))
}

and

const postData = async () =>{
  await fetch(somerandomurl)
  setValues(prevValues => ({...prevValues, admin: false }))
}

Upvotes: 1

Related Questions