1

I have a method in a component. I want to dynamically setState with a key in a nested array of objects.

method = (name, value) => {
    console.log(name)
    //a  //value is 1
    //b  //value is 2
    //c  //value is 3
    this.setState({ [name]:value })
}

when its not nested, it dynamically changes state successfully. However when its nested

 method = (name, value) => {
    this.setState({
        ArrayOfObjects:[{
            [name] : value
    }]
 }

My state becomes

state = {
    ArrayOfObjects: [{
       c: 3
    }]
}

I want

state = {
    ArrayOfObjects: [{
        a: 1,
        b: 2,
        c: 3
    }]

What's wrong?

4
  • Is ArrayOfObjects always an array with just a single (1) object like in your example? If not, does each object have some sort identifier to signal where a given name and value need to be added as property/value to? For example if becomes { ArrayOfObjects: [{ a:1 }, { a:1, b:2 }] }, which object in the array would name of c and value of 3 go to? Commented Oct 31, 2018 at 21:36
  • ArrayOfObjects is always a single object Commented Oct 31, 2018 at 21:45
  • Can I ask why you would need ArrayOfObjects to be an array if it's only going to ever have a single object? Commented Oct 31, 2018 at 21:47
  • I'm using semantic ui and I want to render table rows dynamically. The table component has a jsx attribute tableData which must take an array of objects. Its passed into the renderBodyRow to be mapped Commented Oct 31, 2018 at 21:51

2 Answers 2

1

You could just push an element to the current ArrayOfObjects.

ArrayOfObjects = this.state.ArrayOfObjects;
ArrayOfObjects.push({[name] : value});
this.setState({
    ArrayOfObjects
});

Or using the spread operator:

this.setState({
    ArrayOfObjects: [
        ...this.state.ArrayOfObjects,
        {[name] : value}
    ]
});
Sign up to request clarification or add additional context in comments.

Comments

0

Assuming that ArrayOfObjects is an always an array with single object and that you want to merge name/value into that object:

method(name, value) {
  // make a copy
  const ArrayOfObjects = [...this.state.ArrayOfObjects];
  // merge properties and set dynamic value
  ArrayOfObjects[0] = { ...ArrayOfObjects[0], [name]: value };

  this.setState({
    ArrayOfObjects
  });
}

Here is an example in action.

Hopefully that helps!

4 Comments

Yeah, I've tried using spread operator, same problem. Probably something wrong with my code. Thanks for your time!
Did you review the linked example? You can add name/value and merge it into ArrayOfObjects without losing any properties or affecting other values in state. The key thing here is targeting the first element in the ArrayOfObjects array. It's different than ArrayOfObjects:[{ [name] : value }] as that will always replace the existing object entirely and not merge the properties.
Yup, I reviewed it. My method is only changing the state of the last name/value pair that's passed in. It may be because I'm using ref in my form to capture input value instead. I felt it was better to capture the value when the user submits the form rather than onChange. Is this wrong?
I only added onChange because there wasn't any information provided regarding how method(name, value) is called or how it retrieves the values. It's just being used in the example as a mechanism to pass a name and value to method(name, value) in an interactive way to demonstrate the functionality of the setState() updating and merging state. All the onChange really does is pass values to method(name, value)`, it can really be ignored.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.