Skip to content
Advertisement

Update state object with multiple keys using input id

my state looks like this:

const [options, setOptions] = useState({ numbers: false, animals: false, greetings: false, food: false, colors: false, other: true })

and I’m trying to update a single boolean based on a checkbox.

At first I used a switch statement like so:

    switch (e.target.id) {
      case 'numbers': setOptions((prevState) => ({ ...prevState, numbers: e.target.checked })); break;
      case 'animals': setOptions((prevState) => ({ ...prevState, animals: e.target.checked })); break;
      case 'greetings': setOptions((prevState) => ({ ...prevState, greetings: e.target.checked })); break;
      case 'food': setOptions((prevState) => ({ ...prevState, food: e.target.checked })); break;
      case 'colors': setOptions((prevState) => ({ ...prevState, colors: e.target.checked })); break;
      case 'other': setOptions((prevState) => ({ ...prevState, other: e.target.checked })); break;
      default: break
    }

but I think as I add more options, I’ll want something cleaner, I was hoping something like

setOptions((prevState) => ({ ...prevState, options[e.target.id]: e.target.checked }))

would work but no luck. I also tried

options[e.target.id] = e.target.checked

but it doesn’t do a refresh.

Advertisement

Answer

Your cleaner version is definitely the preferred one but the syntax for computed property names is

{
  [ key ]: value
}

I’d be inclined to use a name attribute instead of id, mainly to avoid accidentally duplicating IDs.

const handleCheckbox = (e) => {
  setOptions(prev => ({
    ...prev,
    [e.target.name]: e.target.checked
  }));
};

You just need to make sure your checkbox elements have appropriate attributes

{Object.entries(options).map(([option, checked]) => (
  <label>
    <input
      type="checkbox"
      name={option}
      checked={checked}
      onChange={handleCheckbox}
    />
    {option}
  </label>
))}
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement