157 votes

Comment utiliser la méthode de cycle de vie getDerivedStateFromProps par opposition à componentWillReceiveProps

Il ressemble componentWillReceiveProps va être complètement éliminée dans les versions à venir, en faveur d'un nouveau cycle de vie méthode getDerivedStateFromProps:statique getDerivedStateFromProps().

Lors de l'inspection, on dirait que vous êtes incapable de faire une comparaison directe entre this.props et nextProps, comme vous pouvez vous en componentWillReceiveProps. Est-il un moyen de contourner cela?

Aussi, elle revient aujourd'hui un objet. Ai-je raison de supposer que la valeur de retour est essentiellement this.setState?

Ci-dessous est un exemple que j'ai trouvé en ligne: État dérivé d'accessoires/état.

Avant

class ExampleComponent extends React.Component {
  state = {
    derivedData: computeDerivedState(this.props)
  };

  componentWillReceiveProps(nextProps) {
    if (this.props.someValue !== nextProps.someValue) {
      this.setState({
        derivedData: computeDerivedState(nextProps)
      });
    }
  }
}

Après

class ExampleComponent extends React.Component {
  // Initialize state in constructor,
  // Or with a property initializer.
  state = {};

  static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.someMirroredValue !== nextProps.someValue) {
      return {
        derivedData: computeDerivedState(nextProps),
        someMirroredValue: nextProps.someValue
      };
    }

    // Return null to indicate no change to state.
    return null;
  }
}

111voto

Oblosys Points 5035

À propos de la suppression de l' componentWillReceiveProps: vous devez être capable de gérer ses utilisations avec une combinaison de getDerivedStateFromProps et componentDidUpdate, voir le Réagir post de blog par exemple les migrations. Et oui, l'objet retourné par getDerivedStateFromProps mises à jour de l'état de manière similaire à un objet passé en setState.

Dans le cas où vous avez vraiment besoin de l'ancienne valeur d'un accessoire, vous pouvez toujours le cache dans votre état avec quelque chose comme ceci:

state = {
  cachedSomeProp: null
  // ... rest of initial state
};

static getDerivedStateFromProps(nextProps, prevState) {
  // do things with nextProps.someProp and prevState.cachedSomeProp
  return {
    cachedSomeProp: nextProps.someProp,
    // ... other derived state properties
  };
}

Tout ce qui n'affectent pas l'état peuvent être mis en componentDidUpdate, et il y a même un getSnapshotBeforeUpdate pour les très bas niveau de stuff.

Mise à JOUR: pour obtenir une sensation pour les nouveaux (et anciens) du cycle de vie des méthodes, la réaction du cycle de vie-visualizer paquet peut être utile.

57voto

Dan Points 16670

Comme nous l' a récemment posté sur les Réagissent blog, dans la grande majorité des cas, vous n'avez pas besoin d' getDerivedStateFromProps à tous.

Si vous voulez juste pour calculer certaines données dérivées, soit:

  1. Faire droit à l'intérieur d' render
  2. Ou, si re-calcul, il est cher, l'utilisation d'un memoization aide comme memoize-one.

Voici la plus simple "après" exemple:

import memoize from "memoize-one";

class ExampleComponent extends React.Component {
  getDerivedData = memoize(computeDerivedState);

  render() {
    const derivedData = this.getDerivedData(this.props.someValue);
    // ...
  }
}

Découvrez cet article de le blog pour en savoir plus.

6voto

mpospelov Points 884

Comme mentionné par Dan Abramov

Faire droit à l'intérieur de rendu

En fait, nous utilisons cette approche avec memoise un pour tout type de proxy d'accessoires pour l'état des calculs.

Notre code se présente de cette façon

// ./decorators/memoized.js  
import memoizeOne from 'memoize-one';

export function memoized(target, key, descriptor) {
  descriptor.value = memoizeOne(descriptor.value);
  return descriptor;
}

// ./components/exampleComponent.js
import React from 'react';
import { memoized } from 'src/decorators';

class ExampleComponent extends React.Component {
  buildValuesFromProps() {
    const {
      watchedProp1,
      watchedProp2,
      watchedProp3,
      watchedProp4,
      watchedProp5,
    } = this.props
    return {
      value1: buildValue1(watchedProp1, watchedProp2),
      value2: buildValue2(watchedProp1, watchedProp3, watchedProp5),
      value3: buildValue3(watchedProp3, watchedProp4, watchedProp5),
    }
  }

  @memoized
  buildValue1(watchedProp1, watchedProp2) {
    return ...;
  }

  @memoized
  buildValue2(watchedProp1, watchedProp3, watchedProp5) {
    return ...;
  }

  @memoized
  buildValue3(watchedProp3, watchedProp4, watchedProp5) {
    return ...;
  }

  render() {
    const {
      value1,
      value2,
      value3
    } = this.buildValuesFromProps();

    return (
      <div>
        <Component1 value={value1}>
        <Component2 value={value2}>
        <Component3 value={value3}>
      </div>
    );
  }
}

Les avantages sont que vous n'avez pas besoin de code de tonnes de comparaison standard à l'intérieur d' getDerivedStateFromProps ou componentWillReceiveProps et vous pouvez sauter les copier-coller d'initialisation à l'intérieur d'un constructeur.

NOTE:

Cette approche est utilisée uniquement pour le proxy d'accessoires pour l'état, dans le cas où vous avez quelques intérieure de l'état de logique, il doit encore être traitées en composant le cycle de vie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X