Как использовать метод жизненного цикла getDerivedStateFromProps вместо componentWillReceiveProps

Похоже, что в следующих выпусках 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;
  }
}

Заголовок должен быть «как заставить все работать, несмотря на то, что команда React делает все, чтобы этому противостоять».

zyrup 17.03.2021 21:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
155
1
157 379
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Об удалении 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

Andrew 03.04.2018 00:09

Я думал использовать свое состояние для хранения предыдущих свойств, но мне действительно хотелось избежать лишнего кода и логики, необходимых для его реализации. Я рассмотрю некоторые другие вопросы, о которых вы говорите. Большое спасибо!

Andrew 03.04.2018 01:39

Необходимость сохранять предыдущую опору в состоянии - это всего лишь шаблонный обходной путь для этого трудного для понимания изменения API React. Для многих разработчиков это выглядит как антипаттерн и регресс. Критикует не вас, Oblosys, а команду React.

AxeEffect 04.05.2018 11:11

@AxeEffect Это потому, что getDerivedStateFromProps никогда не предназначался для запоминания. Пожалуйста, посмотрите мой ответ ниже, где я вместо этого описал рекомендуемый подход.

Dan Abramov 10.06.2018 15:31

это опечатка? Вы скучали по ...? То есть должны мы вернуть весь объект состояния или только ту часть, которая нас интересует.

theprogrammer 27.06.2019 18:30

Вы должны просто вернуть свойства производного состояния. Я обозначил возможные другие производные свойства с помощью .., чтобы избежать путаницы с ..., но // ... лучше.

Oblosys 27.06.2019 19:51

Поскольку мы недавно опубликовано в блоге React,, в подавляющем большинстве случаев вам вообще не нужен getDerivedStateFromProps.

Если вы просто хотите вычислить производные данные, либо:

  1. Сделайте это прямо внутри render
  2. Или, если пересчет требует больших затрат, используйте помощник по запоминанию, например memoize-one.

Вот простейший пример «после»:

import memoize from "memoize-one";

class ExampleComponent extends React.Component {
  getDerivedData = memoize(computeDerivedState);

  render() {
    const derivedData = this.getDerivedData(this.props.someValue);
    // ...
  }
}

Ознакомьтесь с этот раздел сообщения в блоге, чтобы узнать больше.

Если это не требуется в большинстве случаев огромный, то я удивлен, что это было настолько необходимое изменение, которое сломает тысячи рабочих проектов. Похоже, команда React начала с инженерии.

Ska 28.06.2018 12:49

О каком изменении вы говорите? Что сломает рабочие проекты? Никаких критических изменений не было.

Dan Abramov 29.06.2018 17:42

Измените значение componentWillReceiveProps на getDerivedStateFromProps. Это не ломает, а заставляет реорганизовать весь существующий код, что отнимает очень много времени. И, похоже, приносит очень мало пользы, поскольку вы говорите, что не должны использовать его вообще в подавляющем большинстве случаев. Зачем тратить время на смену API на то, что вообще не следует использовать.

Ska 02.07.2018 08:20

Я хотел бы получить ответ на этот комментарий от Дэна Абрамова.

Louis345 20.10.2018 17:48

@DanAbramov есть ли ответ на вопрос, почему это изменение произошло?

Petros Kyriakou 03.01.2019 15:07

На самом деле в наших проектах это используется очень часто. Для отображения таких вещей, как Snackbars на экранах, когда появляются новые данные, 1 пример. componentWillReceiveProps был простым, и он работал. Зачем убирать за эту статическую фигню ...

Oliver Dixon 27.07.2019 11:08

@DanAbramov Мне тоже интересно узнать, почему?

alek kowalczyk 13.08.2019 14:42

@DanAbramov У меня был вариант использования, когда я напрямую (без каких-либо условий) извлекаю данные в componentwillReceive Props и сохраняю результат в состоянии. как лучше всего перейти на новые методы жизненного цикла реакции? (не так легко увидеть один)

gmoniava 28.08.2019 21:39

Как сказал Дан Абрамов

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

прочтите https://www.w3schools.com/REACT/react_lifecycle.asp#:~:text=Lifecycle%20of%20Components,Mounting%2C%20Updating%2C%20and%20Unmounting.

Другие вопросы по теме