何时使用“componentDidUpdate”方法?

IT技术 reactjs
2021-04-03 15:54:34

我写了几十个 Reactjs 文件,但我从未使用过这种componentDidUpdate方法。

有什么典型的例子什么时候需要使用这种方法吗?

我想要一个真实的例子,而不是一个简单的演示。

6个回答

一个简单的例子是一个应用程序,它从用户那里收集输入数据,然后使用 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 进行操作。这也是进行网络请求的好地方,只要您将当前的 props 与之前的 props 进行比较(例如,如果 props 没有改变,则网络请求可能是不必要的)。

感谢您的回答。因此,一种使用情况componentDidUpdate是解决多个 setStates!还有其他想法吗?
2021-05-27 15:54:34
是的,您可以使用回调,但是当/如果有多个连续运行的 setStates 时,问题会变得更加棘手。
2021-05-31 15:54:34
这是一个很好的例子,但它缺少来自 React 文档的关键建议。“这也是进行网络请求的好地方,只要您将当前的 props 与之前的 props 进行比较(例如,如果 props 没有改变,则可能不需要网络请求)。” reactjs.org/docs/react-component.html#componentdidupdate 同样,无论何时setState在 CDU 中调用都应该将调用包装在条件逻辑中。
2021-06-01 15:54:34
我想this.setState({...}, callback)callback平等_commitAutoSave,你怎么看?所以,我认为这个案例可以使用componentDidUpdate方法,但不是必须的,对吗?小提琴
2021-06-17 15:54:34
@novaline 我看到他们在 react-sound 组件github.com/leoasis/react-sound/blob/master/src/index.js 中使用它.. 我不确定他们为什么使用它,但我想我会分享链接让你看看。
2021-06-21 15:54:34

有时您可能会在构造函数或 componentDidMount 中添加来自 props 的状态值,您可能需要在 props 更改但组件已经挂载时调用 setState,因此 componentDidMount 不会执行,构造函数也不会执行;在这种特殊情况下,您可以使用 componentDidUpdate,因为props已更改,您可以使用新props在 componentDidUpdate 中调用 setState。

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()在highchart中使用过。

这是该组件的一个简单示例。

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' }} />;
  }
}

一旦发生更新,就会调用此生命周期方法。componentDidUpdate() 方法最常见的用例是更新 DOM 以响应 prop 或 state 的变化。

您可以在此生命周期中调用 setState(),但请记住,您需要将其包装在一个条件中,以检查状态或props是否与之前的状态发生了变化。setState() 的错误使用会导致无限循环。请看下面的示例,该示例显示了此生命周期方法的典型用法示例。

componentDidUpdate(prevProps) {
 //Typical usage, don't forget to compare the props
 if (this.props.userName !== prevProps.userName) {
   this.fetchData(this.props.userName);
 }
}

请注意,在上面的示例中,我们将当前的 props 与之前的 props 进行比较。这是为了检查props是否与当前相比发生了变化。在这种情况下,如果 props 没有改变,就不需要进行 API 调用。

有关更多信息,请参阅官方文档:

万一怎么办this.fetchData is not a function
2021-06-02 15:54:34
tomrlh 这是一个函数调用
2021-06-19 15:54:34