何时使用React" componentDidUpdate"方法?

时间:2016-08-04 06:12:35

标签: reactjs

我写了几十个React个文件,从不使用componentDidUpdate方法。

是否有需要使用此方法的典型示例?

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

感谢您的回答!

6 个答案:

答案 0 :(得分:54)

一个简单的例子是一个应用程序,它从用户收集输入数据,然后使用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更改,它就会自动保存数据。还有其他方法可以实现它。 {<1}}在需要发生操作 >更新DOM并清空更新队列时特别有用。它可能对复杂的componentDidUpdaterenders或DOM更改最有用,或者当您需要某些内容作为绝对最后要执行的内容时。

上面的例子很简单,但可能证明了这一点。改进可以是限制自动保存可以执行的次数(例如,每10秒最多一次),因为现在它将在每次击键时运行。

我也在这个fiddle上做了一个演示来演示。

有关详细信息,请参阅official docs

  更新发生后立即调用

state。初始渲染不会调用此方法。

     

将此作为在更新组件时对DOM进行操作的机会。只要您将当前道具与之前的道具进行比较(例如,如果道具未更改,则可能不需要网络请求),这也是进行网络请求的好地方。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

此生命周期方法在更新发生时立即被调用。 componentDidUpdate()方法最常见的用例是响应prop或状态更改来更新DOM。

您可以在此生命周期中调用setState(),但请记住,您需要将其包装在某种条件下,以检查状态或支持对先前状态的更改。 setState()的不正确使用可能导致无限循环。 看下面的示例,该示例显示了此生命周期方法的典型用法示例。

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

在上述示例中,请注意,我们正在将当前道具与先前的道具进行比较。这是为了检查道具是否从当前状态发生了变化。在这种情况下,如果道具没有更改,则无需进行API调用。

有关更多信息,请参阅 official docs:

答案 3 :(得分:1)

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));

    }
}

答案 4 :(得分:1)

当状态发生变化时,您需要调用副作用(例如对api的请求-获取,放置,发布,删除)。因此,您需要呼叫componentDidUpdate(),因为已经呼叫了componentDidMount()

在componentDidUpdate()中调用副作用之后,您可以根据then((response) => this.setState({newValue: "here"}))中的响应数据将状态设置为新值。 请确保您需要检查prevPropsprevState以避免无限循环,因为在将状态设置为新值时,componentDidUpdate()将再次调用。

有两个地方可以称为最佳实践的副作用-componentDidMount()和componentDidUpdate()

答案 5 :(得分:0)

我在高图中使用了/* cyrillic-ext */ @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 400; src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; } /* cyrillic */ @font-face { font-family: 'Roboto'; font-style: normal; font-weight: 400; src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v16/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2'); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; . . . etc }

以下是此组件的一个简单示例。

componentDidUpdate()