在ReactJS中获取数据

时间:2018-11-28 07:58:39

标签: javascript reactjs fetch

componentDidMount()中有一个获取请求

componentDidMount() {
   var manufacturers = []

   this.props.participants.map(participant => {
     Get("manufacturer/" + participant.id, "").then(result => {
      manufacturers.push(result)
      console.log(manufacturers)
    });
  });

  this.setState({
    participants: manufacturers
  })
}

console.log(manufacturers)表明数组中存在对象,但是component的状态为空。提取数据后如何正确设置?

Get()函数的代码:

const Config = require('Config')
export async function Get(type, userData) {
    let BaseURL = Config.serverUrl;
    let result = {};
    if(userData)
        result = await fetch(BaseURL+type, {
                method: 'GET',
                headers: new Headers({
                    'Authorization': 'Bearer ' + userData,
                    'Content-Type': 'application/json'
                })
        });
    else
        result = await fetch(BaseURL+type, {
            method: 'GET',
            headers: new Headers({
                'Content-Type': 'application/json'
            })
        });
    let data = await result.json();
    return data;
}

6 个答案:

答案 0 :(得分:1)

由于要进行多个Get调用,而每个调用都是async,因此必须等待直到所有结果均为collected,然后将其设置为状态。您可以使用Promise.all来做到这一点,它可以wait首先解决所有Get的呼叫,然后将数据设置为状态。

我首先创建一个async函数,然后在componentDidMount中调用它。

componentDidMount() {
  this.fetchAllData();
}

然后在此方法内,等待所有Promises解析后,将其设置为有数据的状态。您可能必须将整个函数包装在try..catch块中,以便在由于网络调用失败而导致任何承诺被拒绝时,都可以对其进行适当处理。

fetchAllData = async () => {
  const manufacturers = await Promise.all(
    this.props.participants.map(participant => 
      Get("manufacturer/" + participant.id, ""))
  )
  this.setState(manufacturers)
};

答案 1 :(得分:0)

您需要在Get promise回调中设置setState

componentDidMount() {
   var manufacturers = []

   this.props.participants.map(participant => {
     Get("manufacturer/" + participant.id, "").then(result => {
      manufacturers.push(result)
      console.log(manufacturers)
      this.setState({
        participants: manufacturers
      })
    });
  });
}

答案 2 :(得分:0)

您应将this.setState移到.then内。不完全知道为什么要先将数据推送到厂商阵列。如果您将该阵列用于某些用途。如果您已经有处于状态的结果,则可能不需要Manufacturers数组。如果没有,您可以使用以下结果设置状态:

componentDidMount() {
   var manufacturers = []

   this.props.participants.map(participant => {
     Get("manufacturer/" + participant.id, "").then(result => {
      manufacturers.push(result) // Do you need this?
      console.log(manufacturers)
        this.setState({
          participants: result
        })
    });
  });
}

答案 3 :(得分:0)

问题来自异步逻辑。在提取的this.setState()之外使用then()会使manufacturers属性为空。

您的情况很复杂,您需要在更新状态之前并行解析多个查询。可以使用Promise.all()函数:

componentDidMount() {
  Promise.all(this.props.participants.map(participant =>
    Get("manufacturer/" + participant.id, "")
  ).then(results => {
    this.setState({
      participants: results // or results.map(result => result.data()) ...
    })
 })
}

答案 4 :(得分:0)

在调用ComponentDidMount方法之前初始化状态:

constructor() {
    super();
    this.state = { participants:null }
}

答案 5 :(得分:0)

您应该始终在'then'中更新State或在承诺被解决/拒绝时捕获承诺的块...如下所示

componentDidMount() {
var manufacturers = []

this.props.participants.map(participant => {
 Get("manufacturer/" + participant.id, "").then(result => {
  manufacturers.push(result);

   this.setState({participants: manufacturers});
   console.log(manufacturers);

  });
 });
}

由于您的get函数返回的承诺是异步调用,因此在执行get函数时,在您遇到的情况下,在解析为this.setState()之前,它会跳到下一行代码,因此不会显示更新状态。 永远记住setState()本身是异步的,如果您需要在setState之后执行任何操作,请在setState()的回调可选参数中进行操作,例如:-

this.setState((currentState)=>{
 // you can access the currentState here
 },()=>{
 //your callback... here you can access directly this.state since it is guranteed 
  //that it will be updated state always
});