web-dev-qa-db-fra.com

prevState dans ComponentDidUpdate est le currentState?

J'ai utilisé componentDidUpdate() dans le passé et cela a fonctionné comme prévu.

Cette fois, cependant, j'ai

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

et true n'est jamais connecté. J'ai connecté les deux objets d'état à la console et découvert qu'ils étaient exactement les mêmes: l'état actuel.

Est-ce un bug? Qu'est-ce que j'oublie ici?

Je vous remercie.

Edit: j'ai essayé de faire la même chose avec componentWillUpdate(nextProps, nextState) et encore une fois, c'est le même objet.

Edit 2: Je change d'état en faisant:

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

Dans le code ajouté, vous modifiez un objet de référence en modifiant simplement une propriété sur cet objet. Cela signifie qu'éventuellement nextProps et previousProps font essentiellement référence à la même référence.

Il n’est donc pas surprenant que votre componentDidUpdate n’ait pas trouvé de différence.

Ce que vous devez faire, c'est créer une nouvelle version de votre objet et l'utiliser pour définir l'état, comme suit:

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

ou si vous n'avez pas l'opérateur de propagation, quelque chose comme

this.setState( { object: Object.assign({}, object, { [field]: value }) } );
7
Icepickle

notez que: 

composantDidUpdate () ne sera pas appelé si shouldComponentUpdate () renvoie 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);
    }
}

dans certains cas, il vaut mieux utiliser quelque chose comme la méthode lodash isEqual pour comparer en profondeur votre état/vos accessoires lorsque vous utilisez shouldComponentUpdate:

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

si vous avez des accessoires sophistiqués, cela améliorera vos performances, car aucun rendu inutile ne se produit

1
toufek khoury

Merci Icepickle pour votre commentaire qui a résolu le problème.

Au lieu de faire

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

J'ai fait

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

Merci encore.

0
Daniel Valderrama