javascript - update - react getderivedstatefromprops
Cómo utilizar el método de ciclo de vida getDerivedStateFromProps en lugar de componentWillReceiveProps (3)
Parece que
componentWillReceiveProps
se eliminará por completo en las próximas versiones, a favor de un nuevo método de ciclo de vida
getDerivedStateFromProps
.
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
Tras la inspección, parece que ahora no puede hacer una comparación directa entre
this.props
y
nextProps
, como puede hacer en
componentWillReceiveProps
.
¿Hay alguna forma de evitar esto?
Además, ahora devuelve un objeto.
¿Estoy en lo cierto al suponer que el valor de retorno es esencialmente
this.setState
?
A continuación se muestra un ejemplo que encontré en línea https://github.com/reactjs/rfcs/blob/master/text/0006-static-lifecycle-methods.md#state-derived-from-propsstate
antes de
class ExampleComponent extends React.Component {
state = {
derivedData: computeDerivedState(this.props)
};
componentWillReceiveProps(nextProps) {
if (this.props.someValue !== nextProps.someValue) {
this.setState({
derivedData: computeDerivedState(nextProps)
});
}
}
}
Despué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;
}
}
Acerca de la eliminación de
componentWillReceiveProps
: debe poder manejar sus usos con una combinación de
getDerivedStateFromProps
y
componentDidUpdate
, consulte
la publicación del blog React
para ver migraciones.
Y sí, el objeto devuelto por
getDerivedStateFromProps
actualiza el estado de manera similar a un objeto pasado a
setState
.
En caso de que realmente necesite el valor anterior de un accesorio, siempre puede almacenarlo en caché en su estado con algo como esto:
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
};
}
Cualquier cosa que no afecte el estado se puede poner en
componentDidUpdate
, e incluso hay un
getSnapshotBeforeUpdate
para
getSnapshotBeforeUpdate
de muy bajo nivel.
ACTUALIZACIÓN: para tener una idea de los métodos de ciclo de vida nuevos (y antiguos), el paquete react-lifecycle-visualizer puede ser útil.
Como
publicamos recientemente en el blog React
,
en la gran mayoría de los casos
no necesita
getDerivedStateFromProps
.
Si solo desea calcular algunos datos derivados, ya sea:
-
Hazlo dentro del
render
-
O, si volver a calcularlo es costoso, use un asistente de
memoize-one
comomemoize-one
.
Aquí está el ejemplo más simple "después":
import memoize from "memoize-one";
class ExampleComponent extends React.Component {
getDerivedData = memoize(computeDerivedState);
render() {
const derivedData = this.getDerivedData(this.props.someValue);
// ...
}
}
Consulte esta sección de la publicación del blog para obtener más información.
Como lo menciona Dan Abramov
Hazlo dentro del render
De hecho, utilizamos ese enfoque con una memoria para cualquier tipo de accesorios de proxy para cálculos de estado.
Nuestro código se ve de esta manera
// ./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>
);
}
}
Los beneficios de esto son que no necesita codificar toneladas de
getDerivedStateFromProps
de comparación dentro de
getDerivedStateFromProps
o
componentWillReceiveProps
y puede omitir la inicialización de copiar y pegar dentro de un constructor.
NOTA:
Este enfoque se usa solo para representar los accesorios para que se declaren, en caso de que tenga alguna lógica de estado interno, aún debe manejarse en los ciclos de vida de los componentes.