api中的ComponentDidUpdate()数据以及新数据

时间:2019-06-27 21:53:25

标签: javascript reactjs

我是新来的反应者,我看到了一个类似的示例,但是并没有清楚地说明它们,我也不知道如何解决该问题。我有一个API,新数据已发布到API。 ComponentDidMount()将首次从API初始化数据。 我浏览了文档,发现componentDiUpdate()将始终在添加新数据后重新呈现页面。

到目前为止,这是我的代码:

constructor(props){
  super(props);
  this.state = {
    newData: [],
    dataApi: this.props.getAllData() //method that is using GET_ALL_DATA actions/reducers using fetch(get)
  }
}
// it gets the data
componentDidMount() {
  this.state.dataApi
}

componentDidUpdate(prevProps, prevState){
  this.state.dataApi.then(data => {
    if(prevProps.data != this.props.data) {
      this.setState({newData: data});
    }
  }
}

ComponentDidUpdate()错误:

  

无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。

如何解决此问题?通过在有人发出发布请求时从API获取新数据?谢谢

4 个答案:

答案 0 :(得分:1)

componentDidMount()生命周期方法仅在首次呈现组件时被调用一次。

在您的constructor()中,您不需要对自己的状态做出承诺。相反,您可以删除dataApi并直接调用该方法。在componentDidMount()中,您将进行API调用。 API调用完成后,您可以使用this.setState()

每次更新prop或state值之一时,就会调用componentDidUpdate方法。因此,当您冒险无限循环时,更新其中的状态是一个坏主意。

constructor(props){
      super(props);
      this.state = {
           newData: [], 
      };
}

// it gets the data
componentDidMount() {
    this.props.getAllData().then(data => {
        this.setState({
            newData: data,
         });
    });
}

答案 1 :(得分:0)

如果要在重新渲染之前挂接道具更改,请尝试挂接到componentWillReceiveProps。 componentWillReceiveProps将同步更新状态。

您组件componentDidMount中的

还..代码什么也不做:)

// it gets the data
componentDidMount(){
      this.state.dataApi}

尝试将其替换为

// it gets the data
componentDidMount() {
    this.state.dataApi.then(data => {
        this.setState({
            newData: data,
         });
    });
}

答案 2 :(得分:0)

异步设置状态时(例如,在解决了诺言之后),重要的是确保您的组件仍处于挂载状态,否则,您可能会在未挂载的组件上设置状态(触发您得到的错误)。

为此,您需要设置某种标志(如下面的示例中的this.mounted):

componentDidMount() {
  this.mounted = true;
}

async componentDidUpdate() {
  const data = await someAPICall();
  if (this.mounted && !_.isEqual(this.state.data, data)) { // See comment below
    this.setState({data});
  }
}

componentWillUnmount() {
  this.mounted = false;
}

此外,在将旧数据与新数据进行比较时,您需要执行深度比较(在上面的示例中,我使用lodash isEqual(...))。

浅表比较(即this.state.data !== data)会比较每个对象的引用,无论实际数据如何,它们总是会有所不同,因此会遇到无限循环,因为setState()将触发另一个componentDidUpdate(),依此类推。

答案 3 :(得分:0)

解决了这个问题,谢谢大家: 该问题的解决方案将是:

this.state = {
   allData: [],
   isSubmitted: false
}

async componentDidUpdate(prevProps, prevState){
  if(this.mounted && this.state.isSubmitted){
     const allData = await this.props.getAllData();
     this.setState({isSubmitted: false,
                  allData: allData.data })
  }

componentDidMount(){ 
   this.mounted=true
}

componentWillUnmount() {
   this.mounted = false; 
}

functionAddDataToApi(){
   // some logic
   this.setState({isSubmitted: true})
}