0

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?

robeert
  • 85
  • 1
  • 9

1 Answers1

1

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 }))
}
Ramesh Reddy
  • 10,159
  • 3
  • 17
  • 32
  • What is the difference in updating the state like that? – robeert Apr 25 '21 at 10:40
  • It's recommended to use a functional update when the new state depends on the old state. See [this](https://stackoverflow.com/questions/57828368/why-react-usestate-with-functional-update-form-is-needed). Is your issue resolved? – Ramesh Reddy Apr 25 '21 at 10:42
  • yes it seems to work prefecly now! thanks – robeert Apr 25 '21 at 10:46
  • just one thing i tried removing the functional updating and it seem to work with just checked instead of defaultChecked – robeert Apr 25 '21 at 10:50
  • @robeert Yes, using checked fixed your issue but the functional update is also good to use for reasons stated in that link. – Ramesh Reddy Apr 25 '21 at 10:52