Когда использовать метод React «componentDidUpdate»?

Я написал десяткиReact файлы, никогда не используйтеcomponentDidUpdate метод.

Есть ли типичный пример того, когда нужно использовать этот метод?

Мне нужен пример из реальной жизни, а не простая демонстрация.

Спасибо за ответ!

 Jorge04 авг. 2016 г., 14:46
Я согласен с вами @wintvelt в целом "не используйте другую библиотеку, которая изменяет DOM", но иногда я оказывался без какого-либо другого выбора, например, у jQuery есть несколько замечательных плагинов, которые до сих пор не имеют эквивалента в экосистеме React. , так как последний еще довольно молод.
 slideshowp205 авг. 2016 г., 03:26
@wintvelt Я согласен с тобой. Благодаря ~
 Rajesh04 авг. 2016 г., 08:17
Простой случай, когда вы хотите установить начальное состояние компонента при загрузке.
 Jorge04 авг. 2016 г., 09:05
Я думаю, что наиболее распространенный вариант использования - это когда у вас есть другие библиотеки (jQuery, D3 ...), которые работают непосредственно на DOM, вместе с React. В таких случаях, если другой библиотеке необходимо выполнить преобразования DOM, вы должны использовать componentDidUpdate, чтобы гарантировать, что теневой DOM React сброшен в реальный DOM.
 slideshowp204 авг. 2016 г., 08:42
@Rajesh Можете ли вы объяснить это или привести пример? Спасибо!
 wintvelt04 авг. 2016 г., 14:01
Чтобы уточнить комментарий @ Хорхе: я думаю, что наиболее распространенным случаем будет ЧИТАТЬ с реального DOM после обновления React. Например. когда вы хотите узнать точные размеры элементов DOM или положение элементов DOM в области просмотра. Например. для анимации или переходов, которыми вы хотите управлять. Я определенно рекомендовал бы не использовать jQuery для изменения DOM после того, как реагирует рендеринг. Реакция + другая библиотека меняет ту же часть DOM - плохая идея.

Ответы на вопрос(3)

componentDidUpdate(prevProps){ 

    if (this.state.authToken==null&&prevProps.authToken==null) {
      AccountKit.getCurrentAccessToken()
      .then(token => {
        if (token) {
          AccountKit.getCurrentAccount().then(account => {
            this.setState({
              authToken: token,
              loggedAccount: account
            });
          });
        } else {
          console.log("No user account logged");
        }
      })
      .catch(e => console.log("Failed to get current access token", e));

    }
}

я использовалcomponentDidUpdate() в старшем.

Вот простой пример этого компонента.

import React, { PropTypes, Component } from 'react';
window.Highcharts = require('highcharts');

export default class Chartline extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      chart: ''
    };
  }

  public componentDidUpdate() {
    // console.log(this.props.candidate, 'this.props.candidate')
    if (this.props.category) {
      const category = this.props.category ? this.props.category : {};
      console.log('category', category);
      window.Highcharts.chart('jobcontainer_' + category._id, {
        title: {
          text: ''
        },
        plotOptions: {
          series: {
            cursor: 'pointer'
          }
        },
        chart: {
          defaultSeriesType: 'spline'
        },
        xAxis: {
          // categories: candidate.dateArr,
          categories: ['Day1', 'Day2', 'Day3', 'Day4', 'Day5', 'Day6', 'Day7'],
          showEmpty: true
        },
        labels: {
          style: {
            color: 'white',
            fontSize: '25px',
            fontFamily: 'SF UI Text'
          }
        },
        series: [
          {
            name: 'Low',
            color: '#9B260A',
            data: category.lowcount
          },
          {
            name: 'High',
            color: '#0E5AAB',
            data: category.highcount
          },
          {
            name: 'Average',
            color: '#12B499',
            data: category.averagecount
          }
        ]
      });
    }
  }
  public render() {
    const category = this.props.category ? this.props.category : {};
    console.log('render category', category);
    return <div id={'jobcontainer_' + category._id} style={{ maxWidth: '400px', height: '180px' }} />;
  }
}
Решение Вопроса

Простым примером может служить приложение, которое собирает входные данные от пользователя и затем использует Ajax для загрузки указанных данных в базу данных. Вот упрощенный пример (не запускайте его - могут иметь синтаксические ошибки):

export default class Task extends React.Component {

  constructor(props, context) {
    super(props, context);
    this.state = {
      name: "",
      age: "",
      country: ""
    };
  }

  componentDidUpdate() {
    this._commitAutoSave();
  }

  _changeName = ,(e) => {
    this.setState({name: e.target.value});
  }

  _changeAge = (e) => {
    this.setState({age: e.target.value});
  }

  _changeCountry = (e) => {
    this.setState({country: e.target.value});
  }

  _commitAutoSave = () => {
    Ajax.postJSON('/someAPI/json/autosave', {
      name: this.state.name,
      age: this.state.age,
      country: this.state.country
    });
  }

  render() {
    let {name, age, country} = this.state;
    return (
      <form>
        <input type="text" value={name} onChange={this._changeName} />
        <input type="text" value={age} onChange={this._changeAge} />
        <input type="text" value={country} onChange={this._changeCountry} />
      </form>
    );
  }
}

Поэтому всякий раз, когда компонент имеетstate изменить это будет автоматически сохранять данные. Есть и другие способы его реализации.componentDidUpdate особенно полезно, когда операция должна произойтипосле DOM обновляется и очередь обновлений очищается. Это, вероятно, наиболее полезно на сложныхrenders а такжеstate или DOM меняется, или когда вам нужно что-то, чтобы бытьабсолютно последняя вещь, которая будет выполнена.

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

Я сделал демо на этомиграть на скрипке а также для демонстрации.

Для получения дополнительной информации обратитесь кофициальные документы:

componentDidUpdate() вызывается сразу после обновления. Этот метод не вызывается для начального рендеринга.

Используйте это как возможность работать на DOM, когда компонент был обновлен. Это также хорошее место для выполнения сетевых запросов, если вы сравниваете текущий реквизит с предыдущими реквизитами (например, сетевой запрос может не понадобиться, если реквизиты не изменились).

 Chris04 авг. 2016 г., 10:57
Да, вы можете использовать обратный вызов, однако проблема усложняется, когда / если есть несколько setStates, которые выполняются подряд.
 Sarah30 мая 2017 г., 00:49
@novaline Я вижу, они используют его в компоненте «Звук реакции»github.com/leoasis/react-sound/blob/master/src/index.js .. Я не совсем уверен, почему они используют его, но я решил поделиться ссылкой, чтобы вы посмотрели.
 slideshowp204 авг. 2016 г., 09:52
Я думаюthis.setState({...}, callback),callback равный_commitAutoSave, что ты думаешь? Итак, я думаю, что этот случай можно использоватьcomponentDidUpdate метод, но не должен, я прав?играть на скрипке
 slideshowp205 авг. 2016 г., 03:16
Спасибо за Ваш ответ. Итак, один случай для использованияcomponentDidUpdate это решить несколько setStates! Есть другие идеи?
 Chris21 июн. 2018 г., 23:08
@ theUtherSide, правда. Я добавлю ссылку на этот раздел документов.
 theUtherSide21 июн. 2018 г., 23:02
Это хороший пример, но в нем отсутствуют ключевые рекомендации из документации React. «Это также хорошее место для выполнения сетевых запросов, если вы сравниваете текущий реквизит с предыдущими реквизитами (например, сетевой запрос может не потребоваться, если реквизиты не изменились)».reactjs.org/docs/react-component.html#componentdidupdate  Точно так же каждый раз, когда выsetState в ХДС.

Ваш ответ на вопрос