1

I'm trying to create the following structure in React

{ 
items: 
     {Dogs: [{name: "Snoopy"}, {name: "Lola"}, {name: "Sprinkles"}], 
     Cats: [{name: "Felidae"}, {name: "Garfiled"}, {name: "Cat in the Hat"}] 
}

Using the following function:

 handleAddItem(s) {

  var key = Object.keys(s)[0];
  var value = s[key];

  var allItems = {...this.state.items};

      allItems[key] = allItems[key];
      allItems[key].push({name: value});


  var ourItems = {};
      ourItems = allItems[key];
      ourItems.push({name:  value });

    //  console.log(ourItems);
    // console.log(allItems);

  this.setState({items: allItems});

 }

Why are the key value pair being added to state twice?

1
  • 1
    is the lower case and singular keys dog and cat are typos? shouldn't be in plural dogs, cats? Commented Dec 2, 2017 at 21:25

3 Answers 3

2

Modify your handleAddItem to something like below.

Your method was missing the Object.keys(s)[0]. Object.keys will return an array so for you to get the exact key and assuming it is always a single key object, you need to access the zeroth index.

Also in React do not try to mutate the state variables, always create a deep copy of the array or objects variables using ... or other deep cloning techniques.

handleAddItem(s) {

 //s comes in as an object key/value pair e.g. Dogs: Blackie       

  // Your expected key is at the 0th index
  var key = Object.keys(s)[0];
  var value = s[key];

  // Cloning to prevent state mutations
  var allItems = {...this.state.items};

  var allItems[key] = allItems[key] || [];
      allItems[key].push({name:  value });

  this.setState({items: allItems});
}
Sign up to request clarification or add additional context in comments.

4 Comments

could you look at my updated question. Why are the key value pairs being added to state twice?
Looks like you figured out the problem. You mixed your code with mine. Also, please do not change the content in the question so drastically. Other answers might seem out of context.
seems like the reason is we are passing by reference. But I'm wondering if you can set state this way?
Yeah, because arrays and objects are passed by reference. Although small applications won't see any effect but this can be a great deal when you want to make the application performant because shouldComponentUpdate will affected due to state mutation. medium.com/pro-react/…
1

If you are given a dynamic key, then you can refer to an object key with brackets:

myObj['myKey'] = 'myValue'

You can add arrays and objects with the spread syntax:

const myNewDogs = [{
  name: 'new dog 1'
}, {
  name: 'new dog 2'
}];
const myNewCat = {
  name: 'new cat'
};
const items = {
  dogs: [{
      name: 'dog 1'
    },
    {
      name: 'dog 2'
    },
    {
      name: 'dog 3'
    }
  ],
  cats: [{
      name: 'cat 1'
    },
    {
      name: 'cat 2'
    },
    {
      name: 'cat 3'
    }
  ]
};

items['dogs'] = [...items['dogs'], ...myNewDogs];
items['cats'] = [...items['cats'], {...myNewCat}];
console.log(items);

Note that the object spread syntax is a proposal but already on stage 3 which is safe to use

1 Comment

thats because Object.keys returns an array not A Key.
0

Edit: be aware that the example in your question, is not quite a valid JS object since you have some mismatched brackets.

If you have a structure that looks like this.

const object = {
  items: {
     dogs: [],
     cats: []
  }
}

To append to the nested dogs array, you can do this: object.items.dogs.push({ name: "Snoopy" })

Comments

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.