Il semble que componentWillReceiveProps
soit complètement éliminé dans les versions à venir, au profit d'une nouvelle méthode de cycle de vie getDerivedStateFromProps
: static getDerivedStateFromProps () .
Lors de l'inspection, il semble que vous ne puissiez pas établir de comparaison directe entre this.props
et nextProps
, comme vous pouvez le faire dans componentWillReceiveProps
. Y a-t-il un moyen de contourner cela?
En outre, il retourne maintenant un objet. Ai-je raison de supposer que la valeur de retour est essentiellement this.setState
?
Voici un exemple que j'ai trouvé en ligne: Etat dérivé de props/state .
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;
}
}
À propos de la suppression de componentWillReceiveProps
: vous devriez être en mesure de gérer ses utilisations avec une combinaison de getDerivedStateFromProps
et componentDidUpdate
, voir l'article de blog React) par exemple les migrations. Et oui, l'objet renvoyé par getDerivedStateFromProps
met à jour l'état de la même manière qu'un objet transmis à setState
.
Si vous avez vraiment besoin de l'ancienne valeur d'un accessoire, vous pouvez toujours la mettre en 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'affecte pas l'état peut être mis dans componentDidUpdate
, et il y a même un getSnapshotBeforeUpdate
pour les éléments de très bas niveau.
MISE À JOUR: Pour avoir une idée des nouvelles (et anciennes) méthodes de cycle de vie, le package react-lifecycle-visualizer peut être utile.
Comme nous récemment posté sur le blog React _ , dans la grande majorité des cas vous n'avez pas du tout besoin de getDerivedStateFromProps
.
Si vous souhaitez simplement calculer des données dérivées, vous pouvez soit:
render
memoize-one
.Voici l'exemple "après" le plus simple:
import memoize from "memoize-one";
class ExampleComponent extends React.Component {
getDerivedData = memoize(computeDerivedState);
render() {
const derivedData = this.getDerivedData(this.props.someValue);
// ...
}
}
Découvrez cette section de l'article pour en savoir plus.
Comme mentionné par Dan Abramov
Faites-le bien à l'intérieur
En fait, nous utilisons cette approche avec memoise one pour n’importe quel type d’accessoires proxy permettant d’établir des calculs.
Notre code ressemble à ça
// ./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>
);
}
}
L'avantage de cette méthode est que vous n'avez pas besoin de coder des tonnes de comparaisons entre les éléments getDerivedStateFromProps
ou componentWillReceiveProps
et vous pouvez ignorer l'initialisation du copier-coller dans un constructeur.
NOTE:
Cette approche est utilisée uniquement pour représenter les accessoires par proxy, au cas où vous auriez une logique d'état interne, celle-ci doit encore être traitée dans les cycles de vie des composants.