prevState in componentDidUpdate is the currentStat

2020-07-06 03:07发布

I've used componentDidUpdate() in the past and it has worked as expected.

This time, however, I did

componentDidUpdate(prevProps, prevState) {
    if (prevState.object.someString !== this.state.object.someString) {
        console.log(true);
    }
}

and true is never logged. I logged both state objects to the console and found out they are exactly the same one: the current state.

Is this a bug? What am I missing here?

Thank you.

Edit: I tried to do the same thing with componentWillUpdate(nextProps, nextState) and again, they're the same object.

Edit 2: I'm changing the state by doing:

modifyObject = (field, value) => {
    const { object } = this.state;
    object[field] = value;
    this.setState({ object });
}

3条回答
Ridiculous、
2楼-- · 2020-07-06 03:47

In the added code, you are mutating a reference object by changing just a property on the object. This means that eventually nextProps and previousProps in essence refer to the same reference.

So it is no surprise that your componentDidUpdate didn't find a difference.

What you should do is create a new version of your object, and use that one to set the state, like:

this.setState({ object: { ...object, [field]: value } })

or if you don't have the spread operator, something like

this.setState( { object: Object.assign({}, object, { [field]: value }) } );
查看更多
唯我独甜
3楼-- · 2020-07-06 04:00

Thank you Icepickle for your comment, which solved the problem.

Instead of doing

modifyObject = (field, value) => {
    const { object } = this.state;
    object[field] = value;
    this.setState({ object });
}

I did

modifyObject = (field, value) => {
    const { object } = this.state;
    this.setState({ object: { ...object, [field]: value } });
}

Thanks again.

查看更多
贪生不怕死
4楼-- · 2020-07-06 04:06

note that:

componentDidUpdate() will not be invoked if shouldComponentUpdate() returns false. ref: https://reactjs.org/docs/react-component.html#componentdidupdate

 shouldComponentUpdate(nextProps, nextState) {
    if (this.state.someString !== nextState.someString) {
      return true;
    }
    return false;
  }

componentDidUpdate(prevProps, prevState) {
    if (prevState.someString !== this.state.someString) {
        console.log(true);
    }
}

in some cases better use something like lodash isEqual method to deeply compare your state/props when you use shouldComponentUpdate:

shouldComponentUpdate(nextProps, nextState) {
        return !isEqual(this.state, nextState);
      }

if you have sophisticated props/state this will boost your performance as no wasteful rendering occurs

查看更多
登录 后发表回答