确保在componentDidMount或componentDidUpdate中仅调用一次函数

时间:2019-06-14 15:44:19

标签: javascript reactjs

我想确保一次函数被正确调用一次,具体取决于某些道具和状态。

class MyComponent extends Component {
  state = {
    externalInfoPresent: false,
    infoSaved: false,
  }

  async componentDidMount() {
    await this.props.refreshExternalInfo();
    this.setState({ externalInfoPresent: true });
    if (this.props.externalInfo !== undefined && !this.state.infoSaved) {
      await this.saveMyInfo();
    }
  }

  async componentDidUpdate(prevProps) {
    if (prevProps.externalInfo === this.props.externalInfo || this.state.infoSaved) return;
    await this.saveMyInfo();
  }

  async saveMyInfo() {
    if (this.props.externalInfo === undefined || this.state.infoSaved) return;
    // logic for saving stuff to external service
    this.setState({ infoSaved });
  }

  // render and other stuff
}

saveMyInfo()取决于存在externalInfo

我希望saveMyInfo()仅被调用一次,但是根据我当前的逻辑,它被调用了两次。

3 个答案:

答案 0 :(得分:3)

如果只希望调用一次,则componentDidMount是该位置(在生命周期中仅被调用一次)。因此,您不需要在ComponentDidUpdate中使用它(每次道具更改时(在初始渲染之后)都会调用它!

生命周期:https://hackernoon.com/reactjs-component-lifecycle-methods-a-deep-dive-38275d9d13c0

已更新。.

我认为您只需要在componentdidupdate中调用savemyinfo后将infosaved设置为true(this.setstate({infosaved:true})。

答案 1 :(得分:0)

添加其他标志:

class MyComponent extends Component {
  state = {
    externalInfoPresent: false,
    infoSaved: false,
    saveMyInfoCalled: false,
  }

  async componentDidMount() {
    await this.props.refreshExternalInfo();
    this.setState({ externalInfoPresent: true });
    if (this.props.externalInfo !== undefined && !this.state.infoSaved) {
      await this.saveMyInfo();
    }
  }

  async componentDidUpdate(prevProps) {
    if (this.props.externalInfo !== undefined && !this.state.saveMyInfoCalled && !this.state.infoSaved) {
      await this.saveMyInfo();
    }
  }

  async saveMyInfo() {
    this.setState({saveMyInfoCalled: true});
    if (this.props.externalInfo === undefined || this.state.infoSaved) return;
    // logic for saving stuff to external service
  }

  // render and other stuff
}

如果外部服务失败,您可能应该在某个地方致电this.setState({saveMyInfoCalled: false});。因此,saveMyInfo不会同时被调用多次,但是如果出现问题,则有第二次机会。

答案 2 :(得分:0)

class MyComponent extends Component {
  async componentDidMount() {
    await this.props.refreshExternalInfo();
    await this.saveMyInfo();
  }

  async componentDidUpdate() {
    await this.saveMyInfo();
  }

  async saveMyInfo() {
    // if we don't have the info then skip for now
    if (this.props.externalInfo === undefined || this.infoSaved) return;

    // keep track that we already saved
    this.infoSaved = true;

    // perform save
  }
}