componentWillMount
,componentWillReceiveProps
,componentWillUpdate
Все три функции жизненного цикла имеют оповещения eslint, давайте воспользуемсяUNSAFE_
Новые функции жизненного цикла с префиксом. Не могу не задаться вопросом: «Каково намерение реагировать»? зачем добавлятьUNSAFE_
приставка?
Почему вы предупреждаете эти функции жизненного цикла?
1. КомпонентУиллМаунт
componentWillMount
Жизненный цикл происходит до первого рендеринга, и большинство часто используемых малых партнеров инициализируют данные здесь или асинхронно получают назначения внешних данных. Инициализировать данные, реагировать официально рекомендует размещать их вconstructor
в. И асинхронное получение внешних данных, рендеринг не ждет возврата данных перед рендерингом.
Случай 1: Ниже приведен пример компонента, который прослушивает внешний планировщик событий во время установки.
class Example extends React.Component {
state = {
value: ''
};
componentWillMount() {
this.setState({
value: this.props.source.value
});
this.props.source.subscribe(this.handleChange);
}
componentWillUnmount() {
this.props.source.unsubscribe(this.handleChange );
}
handleChange = source => {
this.setState({
value: source.value
});
};
}
Представьте, что если компонент прерывается при первом рендеринге, он не будет выполняться, потому что компонент еще не закончил рендеринг.componentWillUnmount
Жизненный цикл (注:很多人经常认为componentWillMount和componentWillUnmount总是配对,但这并不是一定的。只有调用componentDidMount后,React才能保证稍后调用componentWillUnmount进行清理
). следовательноhandleSubscriptionChange
Он все равно будет выполняться после успешного возврата данных.setState
Поскольку компонент был удален, происходит утечка памяти. Поэтому рекомендуется писать асинхронный сбор внешних данных вcomponentDidMount
В течение жизненного цикла это обеспечиваетcomponentWillUnmount
Жизненный цикл выполняется при удалении компонента, что позволяет избежать утечек памяти.
Теперь мой друг знает, почему вам нужно его использоватьUNSAFE_componentWillMount
заменятьcomponentWillMount
бар(注意:这里的UNSAFE并不是指安全性,而是表示使用这些生命周期的代码将更有可能在未来的React版本中存在缺陷,特别是一旦启用了异步渲染
)
2. компонентWillReceiveProps
componentWillReceiveProps
Жизненные циклы запускаются при обновлении реквизита. обычно используется дляprops
Параметр состояния обновляется синхронно при обновлении параметра. но если вcomponentWillReceiveProps
Жизненный цикл напрямую вызывает некоторые вызовы родительского компонентаsetState
функция приведет к бесконечному циклу программы.
Случай 2: Ниже приведен подкомпонентcomponentWillReceiveProps
Пример вызова функции родительского компонента для изменения состояния в
...
class Parent extends React.Component{
constructor(){
super();
this.state={
list: [],
selectedData: {}
};
}
changeSelectData = selectedData => {
this.setState({
selectedData
});
}
render(){
return (
<Clild list={this.state.list} changeSelectData={this.changeSelectData}/>
);
}
}
...
class Child extends React.Component{
constructor(){
super();
this.state={
list: []
};
}
componentWillReceiveProps(nextProps){
this.setState({
list: nextProps.list
})
nextProps.changeSelectData(nextProps.list[0]); //默认选择第一个
}
...
}
Как и выше код, вChild
компонентcomponentWillReceiveProps
позвонить напрямуюParent
компонентchangeSelectData
обновитьParent
компонентыstate
изselectedData
стоимость. вызоветParent
компонент перерисовывается, в то время какParent
Запустится повторный рендеринг компонентаChild
компонентcomponentWillReceiveProps
Выполнение функции жизненного цикла. Это приведет к бесконечному циклу. вызвать сбой программы.
Поэтому React официально поставилcomponentWillReceiveProps
заменитьUNSAFE_componentWillReceiveProps
, пусть друзья обращают внимание на дефекты при использовании этого жизненного цикла и обращают внимание на то, чтобы избежать его, например, в приведенном выше примере,Child
существуетcomponentWillReceiveProps
передачаchangeSelectData
судить первымlist
Есть ли обновление, а затем определить, следует ли звонить, вы можете избежать бесконечного цикла.
3. компонент будет обновлять
componentWillUpdate
Жизненный цикл запускается до обновления представления. Обычно он используется для сохранения некоторых данных перед обновлением представления, чтобы упростить назначение после обновления представления.
Случай 3: Ниже приведен случай возврата к текущей позиции полосы прокрутки после загрузки и обновления списка.
class ScrollingList extends React.Component {
listRef = null;
previousScrollOffset = null;
componentWillUpdate(nextProps, nextState) {
if (this.props.list.length < nextProps.list.length) {
this.previousScrollOffset = this.listRef.scrollHeight - this.listRef.scrollTop;
}
}
componentDidUpdate(prevProps, prevState) {
if (this.previousScrollOffset !== null) {
this.listRef.scrollTop = this.listRef.scrollHeight - this.previousScrollOffset;
this.previousScrollOffset = null;
}
}
render() {
return (
`<div>` {/* ...contents... */}`</div>`
);
}
setListRef = ref => { this.listRef = ref; };
}
из-заcomponentWillUpdate
а такжеcomponentDidUpdate
Существует определенная разница во времени между двумя функциями жизненного цикла (componentWillUpdate
После рендеринга, вычисления и обновленияDOM
элемент, который называется последнимcomponentDidUpdate
), если пользователь просто растягивает высоту браузера в этот период времени, тоcomponentWillUpdate
вычислительныйpreviousScrollOffset
не точный. если вcomponentWillUpdate
провестиsetState
операции, возникнет проблема, заключающаяся в том, что при многократном вызове выполняется только одно обновление.setState放
существуетcomponentDidUpdate
, что гарантирует, что он вызывается только один раз за обновление.
Поэтому реагировать официально рекомендует ставитьcomponentWillUpdate
заменитьUNSAFE_componentWillUpdate
. Если вам действительно нужны вышеуказанные случаи, вы можете использовать новую периодическую функцию, добавленную в 16.3.getSnapshotBeforeUpdate
. Ниже будут конкретные инструкции, здесь временная распродажа.
Какие есть альтернативы?
1. получить производное состояние из пропса
getDerivedStateFromProps
Это официальная функция жизненного цикла, недавно добавленная в 16.3.props
Вызывается при изменении, а также при повторном рендеринге родительского компонента. он возвращает новыйprops
стоимость.
Случай 4: следующееgetDerivedStateFromProps
Примеры использования
class Example extends React.Component {
static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.name !== prevState.name) {
return {
name: nextProps.name
}
}
}
}
можно увидеть,getDerivedStateFromProps
получить последниеProps
стоимостьnextProps
,Предыдущийstate
стоимостьprevState
Два параметра, return возвращает объект для обновленияstate
, или вернутьсяnull
Указывает, что обновление не требуетсяstate
. Чтобы быть осторожным,getDerivedStateFromProps
Не могу получить доступthis
, так что если вы хотите идти в ногу сprops
значение для сравнения, только предыдущееprops
значение хранится вstate
как зеркальное изображение. У вас должны быть сомнения здесь, почему бы не поставить предыдущийprops
значение, переданноеgetDerivedStateFromProps
? Официальный анализ выглядит следующим образом:
-
в первый звонок
getDerivedStateFromProps
(после создания экземпляра),prevProps
параметры будутnull
, надо посетитьprevProps
добавлено, когдаif-not-null
Осмотр. -
нет предыдущего
props
Передал этой функции шаг к освобождению памяти в будущих версиях React. (Если React не нужно передавать предыдущие свойства в жизненный цикл, то ему не нужно хранить предыдущие объекты свойств в памяти.)
Подводить итоги,getDerivedStateFromProps
Это официальное новое дополнение для заменыcomponentWillReceiveProps
строить планы. Если вы говорите, что ваш проект будет учитывать совместимость с будущей версией, вместо этого рекомендуется использовать ее.getDerivedStateFromProps
.
2. getSnapshotBeforeUpdate
getSnapshotBeforeUpdate
это сgetDerivedStateFromProps
Вместе новые функции жизненного цикла, добавленные в 16.3. Запускается, когда самое последнее изменение было зафиксировано вDOM
Перед элементом, чтобы компонент мог получить текущее значение перед изменением, любое значение, возвращаемое этим жизненным циклом, будет передано в качестве третьего параметра вcomponentDidUpdate
. Обычно, когда нам нужно обновитьDOM
нужно сохранить передDOM
Этот жизненный цикл используется в текущем состоянии, которое чаще используется дляDOM
Получите положение прокрутки до обновления и восстановите положение прокрутки после обновления. Например, в третьем случае выше,componentWillUpdate
Лучшей альтернативой будетgetSnapshotBeforeUpdate
,getSnapshotBeforeUpdate
прибытьcomponentDidUpdate
только обновленоDOM
эта операция.
Случай 5. Ниже приведена лучшая альтернатива случаю 3.
class ScrollingList extends React.Component {
listRef = null;
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevProps.list.length < this.props.list.length) {
return this.listRef.scrollHeight - this.listRef.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot !== null) {
this.listRef.scrollTop = this.listRef.scrollHeight - snapshot;
}
}
render() {
return (
`<div>` {/* ...contents... */}`</div>`
);
}
setListRef = ref => { this.listRef = ref; };
}
Наконец, оcomponentWillMount
, официальная рекомендация — поместить логическую обработку функции жизненного цикла вcomponentDidMount
Зайти внутрь.
Будет ли он совместим с жизненным циклом класса UNSAFE по мере итерации версии React?
План на сайте React таков:
-
16.3: Введите псевдонимы для небезопасных жизней
UNSAFE_componentWillMount
,UNSAFE_componentWillReceiveProps
а такжеUNSAFE_componentWillUpdate
. (В этом выпуске работают как старые имена жизненного цикла, так и новые псевдонимы.) -
Будущие выпуски 16.x: для
componentWillMount
,componentWillReceiveProps
а такжеcomponentWillUpdate
Включить предупреждения об устаревании. (В этом выпуске работают как старые жизненные имена, так и новые псевдонимы, но старые имена регистрируют предупреждения режима DEV.) -
17.0: удалено
componentWillMount
,componentWillReceiveProps
а такжеcomponentWillUpdate
. (С этого момента будет работать только новое имя жизненного цикла «UNSAFE_».)
В заключение
На самом деле, так много сказано. Всего два момента:
1. Реагировать реализуетcomponentWillMount
,componentWillReceiveProps
а такжеcomponentWillUpdate
Функция трех жизненных циклов неисправна, относительно легко вызвать сбой. Однако из-за старых элементов мы привыкли использовать некоторые старые и разработчики с жизненным циклом этих функций, поэтому, добавляя к нимUNSAFE_
чтобы напомнить тем, кто использует его, чтобы они знали о своих недостатках.
2. React добавляет две новые функции жизненного циклаgetSnapshotBeforeUpdate
а такжеgetDerivedStateFromProps
, цель состоит в том, чтобы достичь, даже если эти три функции жизненного цикла не используютсяТолько эти три жизненных цикла могут достичьфункция.
пс: эта статьяЧастьОпираясь на справочные статьиReact V16.3 Предстоящие изменения в жизненном цикле