Похоже, что в следующих выпусках componentWillReceiveProps будет полностью прекращен в пользу нового метода жизненного цикла getDerivedStateFromProps: статический getDerivedStateFromProps ().
При осмотре кажется, что теперь вы не можете провести прямое сравнение между this.props и nextProps, как вы можете это сделать в componentWillReceiveProps. Есть ли способ обойти это?
Кроме того, теперь он возвращает объект. Правильно ли я предполагаю, что возвращаемое значение - это, по сути, this.setState?
Ниже приведен пример, который я нашел в Интернете: Состояние, полученное из props / state.
Перед
class ExampleComponent extends React.Component {
state = {
derivedData: computeDerivedState(this.props)
};
componentWillReceiveProps(nextProps) {
if (this.props.someValue !== nextProps.someValue) {
this.setState({
derivedData: computeDerivedState(nextProps)
});
}
}
}
После
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;
}
}



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Об удалении componentWillReceiveProps: вы должны иметь возможность обрабатывать его использование с комбинацией getDerivedStateFromProps и componentDidUpdate, см. сообщение в блоге React, например, миграции. И да, объект, возвращаемый getDerivedStateFromProps, обновляет состояние аналогично объекту, переданному setState.
Если вам действительно нужно старое значение опоры, вы всегда можете кэшировать его в своем состоянии примерно так:
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
};
}
Все, что не влияет на состояние, можно поместить в componentDidUpdate, и есть даже getSnapshotBeforeUpdate для очень низкоуровневых вещей.
ОБНОВЛЕНИЕ: Чтобы почувствовать новые (и старые) методы жизненного цикла, может быть полезен пакет визуализатор жизненного цикла реакции.
Тьфу, я перепутала вопрос. Я вообще-то имел ввиду componentWillReceiveProps
Я думал использовать свое состояние для хранения предыдущих свойств, но мне действительно хотелось избежать лишнего кода и логики, необходимых для его реализации. Я рассмотрю некоторые другие вопросы, о которых вы говорите. Большое спасибо!
Необходимость сохранять предыдущую опору в состоянии - это всего лишь шаблонный обходной путь для этого трудного для понимания изменения API React. Для многих разработчиков это выглядит как антипаттерн и регресс. Критикует не вас, Oblosys, а команду React.
@AxeEffect Это потому, что getDerivedStateFromProps никогда не предназначался для запоминания. Пожалуйста, посмотрите мой ответ ниже, где я вместо этого описал рекомендуемый подход.
это опечатка? Вы скучали по ...? То есть должны мы вернуть весь объект состояния или только ту часть, которая нас интересует.
Вы должны просто вернуть свойства производного состояния. Я обозначил возможные другие производные свойства с помощью .., чтобы избежать путаницы с ..., но // ... лучше.
Поскольку мы недавно опубликовано в блоге React,, в подавляющем большинстве случаев вам вообще не нужен getDerivedStateFromProps.
Если вы просто хотите вычислить производные данные, либо:
rendermemoize-one.Вот простейший пример «после»:
import memoize from "memoize-one";
class ExampleComponent extends React.Component {
getDerivedData = memoize(computeDerivedState);
render() {
const derivedData = this.getDerivedData(this.props.someValue);
// ...
}
}
Ознакомьтесь с этот раздел сообщения в блоге, чтобы узнать больше.
Если это не требуется в большинстве случаев огромный, то я удивлен, что это было настолько необходимое изменение, которое сломает тысячи рабочих проектов. Похоже, команда React начала с инженерии.
О каком изменении вы говорите? Что сломает рабочие проекты? Никаких критических изменений не было.
Измените значение componentWillReceiveProps на getDerivedStateFromProps. Это не ломает, а заставляет реорганизовать весь существующий код, что отнимает очень много времени. И, похоже, приносит очень мало пользы, поскольку вы говорите, что не должны использовать его вообще в подавляющем большинстве случаев. Зачем тратить время на смену API на то, что вообще не следует использовать.
Я хотел бы получить ответ на этот комментарий от Дэна Абрамова.
@DanAbramov есть ли ответ на вопрос, почему это изменение произошло?
На самом деле в наших проектах это используется очень часто. Для отображения таких вещей, как Snackbars на экранах, когда появляются новые данные, 1 пример. componentWillReceiveProps был простым, и он работал. Зачем убирать за эту статическую фигню ...
@DanAbramov Мне тоже интересно узнать, почему?
@DanAbramov У меня был вариант использования, когда я напрямую (без каких-либо условий) извлекаю данные в componentwillReceive Props и сохраняю результат в состоянии. как лучше всего перейти на новые методы жизненного цикла реакции? (не так легко увидеть один)
Как сказал Дан Абрамов
Do it right inside render
На самом деле мы используем этот подход с memoise one для любого типа прокси для констатации вычислений.
Наш код выглядит так
// ./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>
);
}
}
Его преимущества заключаются в том, что вам не нужно кодировать тонны шаблонов сравнения внутри getDerivedStateFromProps или componentWillReceiveProps, и вы можете пропустить инициализацию копирования и вставки внутри конструктора.
ПРИМЕЧАНИЕ:
Этот подход используется только для проксирования свойств в состояние, в случае, если у вас есть внутренняя логика состояния, ее все еще нужно обрабатывать в жизненных циклах компонентов.
getDerivedStateFromProps используется всякий раз, когда вы хотите обновить состояние перед рендерингом и обновить состояние реквизита.
GetDerivedStateFromPropd обновляет значение статистики с помощью значения props
Заголовок должен быть «как заставить все работать, несмотря на то, что команда React делает все, чтобы этому противостоять».