React: A doubt behaviour using the PureComponent

Created on 19 Aug 2018  路  5Comments  路  Source: facebook/react

What is the current behavior?

I've met a strange behaviour using PureComponent:

It's normal to unincrease the number when click the add button as follow(shallowEqual return true):

class B extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
    this.click = this.click.bind(this);
  }

  click() {
    this.setState({
      count: ++this.state.count
    });
  }

  render() {
    return (
      <div>
        <button onClick={this.click}>add</button>
        <div>{this.state.count}</div>
      </div>
    );
  }
}

but I'm doubt it's normal to increase the number when using like follow: link

click() {
  const state = Object.assign({}, this.state);

  this.setState({
    count: ++state.count
  });
}

In my option, the effect of { count: ++this.state.count } is same as { count: ++state.count }. I don't know why the second way can do it ? Thanks for replying.

Most helpful comment

@MuYunyun, your ++this.state.count have already change the state to new version

const t = ++this.state.count
console.log(t === this.state.count) // => true
this.setState({
  count: t
})

All 5 comments

@MuYunyun when you use Object.assign you copy the values of this.state into the target object https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

They are not the same object anymore

const state = Object.assign({}, this.state)

this.state !== state // true

Because of that, it is safe to use ++ operator on that object since is not the this.state object anymore, which means you are not mutating this.state directly.

Also, I wouldn't use Object.assign for this use case since you don't need to copy all the values for this operation.

I would do this:

click() {
  this.setState({
    count: this.state.count + 1
  });
}

The recommended way is

this.setState(state => ({
  count: state.count + 1
}))

@yordis Thanks for reply very much. Maybe I want to know about a little more.

const state1 = {
  count: 1
}

const state2 = {
  count: 1
}

state1 !== state2  // true
state1.count === state2.count // true

I've known the effect of Object.assign() is to create another Obj, so it's ok state1 !== state2, but the value of their count is equal, so state1.count === state2.count.

I think ++this.state.count or ++state.count is only the value like the value of the count as above. Is the problem in ++ operation?

@MuYunyun, your ++this.state.count have already change the state to new version

const t = ++this.state.count
console.log(t === this.state.count) // => true
this.setState({
  count: t
})

@AliasT It's surprised. 馃憤 I understand, Thanks.

I've writen a post about this issue in Chinese.

Was this page helpful?
0 / 5 - 0 ratings