繁体   English   中英

在ReactJS中获取数据

[英]Fetch data in ReactJS

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)显示数组中有对象,但是组件的状态为空。 提取数据后如何正确设置?

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

由于您要进行多个Get调用,并且每个调用都是async ,因此必须等待直到所有结果collected ,然后将其设置为state。 您可以使用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)
};

您需要在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
      })
    });
  });
}

您应该将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
        })
    });
  });
}

问题来自异步逻辑。 在提取的then() this.setState()外部使用this.setState()会导致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()) ...
    })
 })
}

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

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

您应始终在'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
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM