New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A doubt behaviour using the PureComponent #13438

Closed
MuYunyun opened this Issue Aug 19, 2018 · 5 comments

Comments

Projects
None yet
4 participants
@MuYunyun

MuYunyun commented Aug 19, 2018

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.

@yordis

This comment has been minimized.

Show comment
Hide comment
@yordis

yordis Aug 19, 2018

@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
  });
}

yordis commented Aug 19, 2018

@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
  });
}

@gaearon gaearon closed this Aug 19, 2018

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Aug 19, 2018

Member

The recommended way is

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

gaearon commented Aug 19, 2018

The recommended way is

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

This comment has been minimized.

Show comment
Hide comment
@MuYunyun

MuYunyun Aug 20, 2018

@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 commented Aug 20, 2018

@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?

@AliasT

This comment has been minimized.

Show comment
Hide comment
@AliasT

AliasT Aug 20, 2018

@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 commented Aug 20, 2018

@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
})
@MuYunyun

This comment has been minimized.

Show comment
Hide comment
@MuYunyun

MuYunyun Aug 20, 2018

@AliasT It's surprised. 👍 I understand, Thanks.

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

MuYunyun commented Aug 20, 2018

@AliasT It's surprised. 👍 I understand, Thanks.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment