Tamas
Tamas

Reputation: 11214

Store checkbox values as array in React

I have created the following demo to help me describe my question: https://codesandbox.io/s/dazzling-https-6ztj2

I have a form where I submit information and store it in a database. On another page, I retrieve this data, and set the checked property for the checkbox accordingly. This part works, in the demo this is represented by the dataFromAPI variable.

Now, the problem is that when I'd like to update the checkboxes, I get all sorts of errors and I don't know how to solve this. The ultimate goal is that I modify the form (either uncheck a checked box or vice versa) and send it off to the database - essentially this is an UPDATE operation, but again that's not visible in the demo.

Any suggestions?

Also note that I have simplified the demo, in the real app I'm working on I have multiple form elements and multiple values in the state.

Upvotes: 0

Views: 580

Answers (3)

harisu
harisu

Reputation: 1406

As regard your example in the codesandbox you can get the expected result using the following snippet

//the idea here is if it exists then remove it otherwise add it to the array.
 const handleChange = e => {
    let x = data.topics.includes(e.target.value) ? data.topics.filter(item => item !== e.target.value): [...data.topics, e.target.value]
    setQuestion({topics:x})

  };

So you can get the idea and implement it in your actual application. I noticed the problem with your code was that you changed the nature of question stored in state which makes it difficult to get the attribute topics when next react re-renders Also you were directly mutating the state. its best to alway use functional array manipulating methods are free from side effects like map, filter and reduce where possible.

Upvotes: 0

Raphael Ben Hamo
Raphael Ben Hamo

Reputation: 166

I recommend you to work with an array of all the id's or whatever you want it to be your list's keys and "map" on the array like here https://reactjs.org/docs/lists-and-keys.html. It also helps you to control each checkbox element as an item.

Upvotes: 1

Brian Thompson
Brian Thompson

Reputation: 14355

Neither your add or delete will work as it is.

Array.push returns the length of the new array, not the new array.

Array.splice returns a new array of the deleted items. And it mutates the original which you shouldn't do. We'll use filter instead.

Change your state setter to this:

// Since we are using the updater form of setState now, we need to persist the event.
e.persist(); 
setQuestion(prev => ({
  ...prev,
  [e.target.name]: prev.topics.includes(e.target.value)
      // Return false to remove the part of the array we don't want anymore
    ? prev.topics.filter((value) => value != e.target.value)
      // Create a new array instead of mutating state
    : [...prev.topics, e.target.value] 
}));

Upvotes: 0

Related Questions