Parece que componentWillReceiveProps se eliminará por completo en las próximas versiones, a favor de un nuevo método de ciclo de vida getDerivedStateFromProps : static getDerivedStateFromProps() .
Tras la inspección, parece que ahora no puede hacer una comparación directa entre this.props y nextProps , como puede hacerlo en componentWillReceiveProps . ¿Hay alguna forma de evitar esto?
Además, ahora devuelve un objeto. ¿Estoy en lo correcto al suponer que el valor de retorno es esencialmente this.setState ?
A continuación se muestra un ejemplo que encontré en línea: Estado derivado de props/estado .
Antes
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 : debería poder manejar sus usos con una combinación de getDerivedStateFromProps y componentDidUpdate , consulte la publicación de blog de React para ver ejemplos de 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 necesites el valor anterior de un accesorio, siempre puedes almacenarlo en caché en tu 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 cosas de muy bajo nivel.
ACTUALIZACIÓN: para tener una idea de los nuevos (y antiguos) métodos de ciclo de vida, el paquete react-lifecycle-visualizer puede ser útil.
Correcta
Como publicamos recientemente en el blog de React , en la gran mayoría de los casos no necesita getDerivedStateFromProps en absoluto
Si solo desea calcular algunos datos derivados, ya sea:
Hazlo bien dentro del render
O, si volver a calcularlo es costoso, use un asistente de memorización como memoize-one .
Aquí está el ejemplo "después" más simple:
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. es correcto
Como lo menciona Dan Abramov
Hazlo bien dentro del render
De hecho, usamos ese enfoque con memoise one para cualquier tipo de accesorios de proxy para calcular el 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 repeticiones 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 enviar los accesorios al estado, en caso de que tenga alguna lógica de estado interna, aún debe manejarse en los ciclos de vida de los componentes.