0
var DENEMEJSON = React.createClass({
getInitialState: function() { return {
    arrayone:[{"id":"1","city":"New York"},{"id":"2","city":"Brooklyn"}],
    arraytwo:[{"id":"101","city":"Hamburg"},{"id":"102","city":"Schalke"}]

}


},
buttonFunc(){
    var str=this.state.arrayone;
    str[0].city="Tokyo";

    this.setState({arrayone:str});
    this.setState({arraytwo:str});
},
buttonFunc2(){
var str=this.state.arrayone;
    str[0].city="Pakistan";
    console.log(JSON.stringify(this.state.arrayone));
    console.log(JSON.stringify(this.state.arraytwo));
    this.setState({arrayone:str});
},

 render: function () {
      return (      <div>
        <button onClick={this.buttonFunc}/>
        <button onClick={this.buttonFunc2}/>
        {JSON.stringify(this.state.arrayone)}
        {JSON.stringify(this.state.arraytwo)}</div>
             )
  }//end return

});

When I click the first button the code does what I want. It sets the arrayone[0].city and arraytwo[0].city value to the Tokyo like that.

arrayone : [{"id":"1","city":"Tokyo"},{"id":"2","city":"Brooklyn"}]

arraytwo : [{"id":"1","city":"Tokyo"},{"id":"2","city":"Brooklyn"}]

And when I click the second button I only want to set arrayone[0].city value to Pakistan.(not arraytwo).

But the code set both arrayone[0].city and arraytwo[0] value to Pakistan.

Why it sets the arraytwo[0].value to Pakistan?

What can I do to solve this problem?

3
  • You shouldn't call setState twice in one method. Combine the two setState calls in buttonFunc like this: this.setState({arrayone: str, arraytwo: str}) Commented Jan 22, 2016 at 21:58
  • I tried that but still the same result. Commented Jan 22, 2016 at 22:06
  • I wasn't suggesting it as a fix to your problem - just best practice. Commented Jan 23, 2016 at 0:11

3 Answers 3

3

Your str is a reference to this.state.arrayone, and you are setting arraytwo with str.

So when arrayone changes, arraytwo changes too. It's a bad idea to set your str directly with this.state.arrayone. Instead you should clone the state to be able to change what you want to change and update your state ONLY in setState.

var cloneArrayone = JSON.parse(JSON.stringify(this.state)).arrayone;
cloneArrayone[0].city = "Tokyo";

this.setState({
  arrayone: cloneArrayone,
  arraytwo: cloneArrayone
});

Here is an example that works: https://jsfiddle.net/snahedis/69z2wepo/28552/

Sign up to request clarification or add additional context in comments.

Comments

1

Your mistake is setting arrayone and arraytwo to THE SAME OBJECT REFERENCE when you click the first button.

buttonFunc(){
  var str=this.state.arrayone;
  str[0].city="Tokyo";

  this.setState({arrayone:str});
  this.setState({arraytwo:str});
},

so when you get arrayone and change the object's value

var str=this.state.arrayone;
str[0].city="Pakistan";

You changed both arrayone and arraytwo's referenced object

Comments

0

The problem occurs when you set both arrayone and arraytwo to str.

this.setState({arrayone:str});
this.setState({arraytwo:str});

When doing this, both are being assigned a reference to the same object, so any changes made to that object will be made to both of them.

One way around this would be to set both of them separately:

var str = this.state.arrayone;
var str2 = this.state.arraytwo;

str[0].city="Tokyo";
str2[0].city="Tokyo";

this.setState({arrayone:str});
this.setState({arraytwo:str2});

Or, you could clone the str object to make a second, independent copy of it:

var str = this.state.arrayone;

str[0].city="Tokyo";

var strCopy = JSON.parse(JSON.stringify(str));

this.setState({arrayone:str});
this.setState({arraytwo:strCopy});

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.