1

I know that similar questions were asked before, but what if i don't want to set the entire state, only one of its properties, to a variable? Something like this:

var initialProperty = {
  name: '',
  id: 0,
  type: ''
}

class Example extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      otherProperty: '',
      targetProperty: initialProperty
      //at the start of the Component, everything works fine.
      //the targetproperty is set to initialproperty
    }
  }
  //by the time, the targetproperty was changed from the initial in the component
  //but if i click a button, i want to set targetproperty to the initialproperty
  somethingHappensOnClick = () => {
    this.setState({targetProperty: initialProperty})
    //unfortunately, the targetproperty wasn't set to the initial.
  }
}

Am I doing something wrong? Why targetProperty doesn't change?

StackedQ
  • 3,999
  • 1
  • 27
  • 41

2 Answers2

2

This is happening because, in js array and object get copied by reference. So when you are setting

targetProperty: initialProperty

targetProperty will get the reference of initialProperty, and all the changes that you will do to targetProperty, will get applied to initialProperty as well.

Idea is, create a new object each time, instead of copying the reference.

Write it like this:

var initialProperty = {
  name: '',
  id: 0,
  type: ''
}

class Example extendds React.Component{
  constructor(props){
    super(props);
    this.state = {
      otherProperty: '',
      targetProperty: Object.assign({}, initialProperty) // or {...initialProperty}
    }
  }

  somethingHappensOnClick = () => {
    this.setState({targetProperty: Object.assign({}, initialProperty)})
  }
}
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
  • Unfortunately, yes. What i'm thinking about, is that i have a function in my code which also affects the `targetProperty` (named here). In my code, I have an input field, and two buttons. If the input field changes, it calls a function which sets the this.state.targetproperty.name with: `this.setState(Object.assign(this.state.targetProperty, {name: event.target.value}))`. And the `somethingHappensOnclick is called when the user clicks on any of the two buttons, reseting the targetproperty. It's possible that the onchange and onclick conflitcs with each other? –  May 12 '18 at 09:21
1

When you are setting targetProperty : initialProperty what happens is

initialProperty--->some_memory_location_x
//after doing targetProperty: initialProperty
targetProperty---->some_memory_location_x

so when you are mutating the targetProperty you are actually changing the values in the memory some_memory_location_x which is where your initialProperty is also pointing at so when you setState again, your targetProperty value doesn't change so try doing the way @Mayank Shukla Pointed out so that you don't mutate values

aravind_reddy
  • 5,236
  • 4
  • 23
  • 39