在getDetails()中设置状态会发生无限循环

时间:2019-05-21 10:06:26

标签: javascript reactjs

    this.state = {
  data: [],
  details: []

}

     componentDidMount() {
this.getDetails()
this.getCountries()

}

getCountries() {
Utils.rest('POST', 'https:///api-spot-get-all', {
  country: '',
  windProbability: ''
}).then(async (r) => {
  const data = await r.json();
  this.setState({
    data: data.result
  })
}).catch(err => {
  console.log(err.message);
});

}

`getDetails() {
return new Promise((resolve, reject) => {
  let details_list = [];
  this.state.data.map(item => {
    return (
      Utils.rest('POST', 'https:///api-spot-get-details', {
        spotId: item.id
      })
      .then(async (r) => {
        const details_item = await r.json()
console.log(`Loaded ${details_list.length} item ...(of ${this.state.data.length})`);
        if (details_list.length === this.state.data.length) {
          await resolve(details_list)
        }
        details_list.push(details_item.result);
      })
    );
  })
})

}`

 render() {

返回(        {         this.state.data.map((item,key)=> {           返回(                          {item.id}             {item.id}                        );         })       }

这是我的代码。第一次通话后,我收到ID,并将其作为输入传递给第二次通话

4 个答案:

答案 0 :(得分:2)

我认为这是因为您正在this.getCountries()函数中调用render。因此,在每个渲染中都会调用该函数,这会导致设置新状态的新请求,该请求将触发新渲染等,从而创建无限循环。因此,如果您删除了从render函数中调用的函数,那么它应该可以工作。

答案 1 :(得分:1)

这是一个基本示例:

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const  myarray=[1,2,3,4,5]

  const mytable=myarray.map((item,key)=>{return(
    <table key={key}> 
      <tr><td>id</td><td>{item}</td></tr>
    </table>)
    })
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      {mytable}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

您可以在渲染器中创建一个const,然后在after之后使用它,这样您就可以尝试代码执行类似的操作:

render() {
        const myComponent=  this.state.data.map((item, key) => { return (
                     <div key={key}>
                          <span>{item.it}</span>
                     </div>
                    ) });
        return (
          {myComponent}
        ) 
  }

我使用过,例如,您可以使用想要的构造函数,就像我使用表的第一个示例中一样。

答案 2 :(得分:0)

请注意,您正在getDetails中调用render方法。渲染不是添加修改内部状态的方法的好地方。请检查反应doc以获取更多详细信息。

答案 3 :(得分:0)

那里有很多奇怪的事情。首先,getDetails返回一个Promise,但是Promise在任何地方都无法解决。它的用法应类似于:

getDetails()
.then(data => {
  // do something with the data
}, error => {
  // manage here the error
}):

此外,this.state.data.map应该是this.state.data.forEach,并从内部删除return,因为您不需要在外部返回任何内容

另一方面,getCountries存在问题。它的名称表示它是GET,但API调用会发送POST。

在弄清这一点之后,在getDetails内,您将使用在getCountries中检索到的数据,因此,其调用应位于在getCountries内解析的请求中,或者更改getCountries承诺,并做类似的事情:

this.getCountries()
.then(data => {
  this.getDetails();
});

您无需担心getDetails调用何时结束,因此不需要返回Promise。

最后,render函数应看起来像这样:

render() {
  return (
    <div>
      {this.state.data.map((item, key) =>
        <div key={key}>{item.id} - {item.id}</div>
      )}
    </div>
  )
}

此后,它应该或多或少地正常工作。不过,我必须警告您。可能您需要做些简单的事情来熟悉React的流程以及如何正确使用状态和JS的异步函数。