2

If I have something like the following:

export default class Questions extends Component {

  state = {
    questions: [
      {value: 'value one, required: true},
      {value: 'value two, required: true},
      {value: 'value two, required: true} 
    ]
  };
...

...and I want to change the middle object's required to false, what would be the best way? So I would end up with:

questions: [
  {value: 'value one, required: true},
  {value: 'value two, required: false},
  {value: 'value two, required: true} 
]

I tried:

_toggleRequired = (index) => {
  this.setState({
    questions[index].required = !questions[index].required
  })
}; 

... but it's giving me a syntax error on the first [index]. Isn't it also probably best to return a new array instead of mutating the existing one?

TIA!

D Durham
  • 1,243
  • 2
  • 20
  • 42
  • What you have is simple not a valid objet literal. Have you ever seen `foo({bar = baz})` anywhere? – Felix Kling Apr 05 '16 at 17:05
  • There is also this for redux: http://stackoverflow.com/q/35592078/218196 . – Felix Kling Apr 05 '16 at 17:07
  • It's not a exact duplicate, I have an array of objects,,, the duplicate reference is an object - not an array. I am also not clear on the point you are trying to make - if there is one. Marking it as an exact duplicate when it is not does not help or even come close to an answer. – D Durham Apr 05 '16 at 17:17
  • Did you even read the accepted answer? Did you try to apply it to your use case? Did you have a look at https://facebook.github.io/react/docs/update.html, as the answer recommends, and read about the methods specifically available for arrays? (FWIW, an array is also an object) – Felix Kling Apr 05 '16 at 17:21
  • @FelixKling To be honest, if I didn't already understand what's going on here, I don't think that duplicate post would have been very helpful. I'm sure there *is* a duplicate somewhere, but I wouldn't say it was that one. Where did the answer on this thread go? It was good, clear, and succinct. – Aaron Beall Apr 05 '16 at 17:31
  • Yes, yes, and yes... but the syntax between what is shown there and and what I specifically asked for are different, which is why I asked. Never mind though because I will look somewhere else for help in hopes that I might get a reply with a simple precise example based on my use case instead of sent to read a ton of stuff that is different or half of which doesn't even apply. I usually get exactly that here... guess deleting an answer that was helpful while I was reading it says this sites powers may need review. – D Durham Apr 05 '16 at 17:33
  • Thank you @Aaron for better stating my point. I too was wondering why the answer that I was pursuing went *poof* – D Durham Apr 05 '16 at 17:34
  • @DDurham: Because the author of the answer deleted it. – Felix Kling Apr 05 '16 at 17:35
  • @DDurham Typically, we don't want to mutate our state objects, we always want to create new ones. See Facebook's immutability JS blog posts. And while this post makes reference to updating a particular entry in an array, this question could be applied on the whole as "how do I update objects in state". Basically, you modify the entry your interested in, and create an object with that change, as well as with all the previous state. – lux Apr 05 '16 at 17:36
  • If you expect copy&paste solutions then I think you have to wrong expectations of Stack Overflow. Here is an another question that is specifically about arrays, if that helps you more: http://stackoverflow.com/q/35303581/218196 . – Felix Kling Apr 05 '16 at 17:36
  • Comments are getting deleted now, too... I've entered some very strange SO thread. :) I think the updated duplicate is much clearer (at the time of writing this comment, heh). – Aaron Beall Apr 05 '16 at 17:39
  • 2
    If you need a concrete example of how to apply the suggestion in the accepted answer to an array, here it is: `var newQuestions = update(this.state.questions, {[index]: {required: { $set: !questions[index].required } });`. All I changed was the property names and targeted the right array element. – Felix Kling Apr 05 '16 at 17:43
  • Thank you... some of us are fairly new to JS in general, let alone ES/6/7/2015/2017, so it isn't always easy to match apples to oranges (at least as we see them). If I could find one to copy and paste, I wouldn't ask. I have found that sometimes it the right combination of keywords in the search, but I do always look before I post – D Durham Apr 05 '16 at 18:00

1 Answers1

2

If you don't want to deal with immutable objects than this is what I recommend. If you create a new array of objects from the current state, make your changes to the object at the particular index, and then save that object as the state it should accomplish what you're trying to do.

_toggleRequired = (index) => {
  let q = this.state.questions;
  q[index].required = !q[index].required
  this.setState({questions : q });
}; 
erichardson30
  • 4,984
  • 8
  • 26
  • 47
  • React doesn't really allow you to setState on an attribute of an object.? Are you kidding. It allows. – Ved Apr 05 '16 at 17:07