如何在componentDidMount React中进一步完成之前完全完成获取数据并将其分配给组件状态? [英] How to finish Fetch data completely and assign it to component state before proceeding further in componentDidMount React?
问题描述
我必须执行多个提取查询.根据我的第一个查询,我必须在收到所有i后再进行多个其他查询,我应该能够将数据分配给react组件状态.看来我是在fetch方法完成之前将值分配给组件状态,因此它们显示为空数组.
I have to perform multiple fetch queries. Based on my first query i have make to make a multiple other queries after receiving all the i should be able to assign the data to the react component state. It appears that i am assigning the values to the component state before the fetch method is finished and hence they appear empty array.
我尝试过从外部移除内部获取方法并执行查询.
I have tried by removing the inner fetch method outside and performing the query.
import React, { Component } from 'react';
import './App.css';
import Sensors from './iot/Sensors';
class App extends Component {
constructor (props) {
super (props);
this.state = {
status: 'disconnected',
devices: [],
dataPoints: []
};
}
componentDidMount() {
// Get Zigbee devices
fetch('http://localhost:3000/ssapi/zb/dev')
.then((res) => res.json())
.then((data) => {
this.setState({
devices : data
})
data.map((device) => {
const dataPoint = []
JSON.parse(device.metadata).dataGroups.map((datagroup) =>{
const url = 'http://localhost:3000/ssapi/zb/dev/' + device.id + '/ldev/' + datagroup.ldevKey + '/data/' + datagroup.dpKey;
fetch(url)
.then((res) => res.json())
.then((data) =>{
dataPoint.concat(data)
console.log('Data', data);
console.log('Inside dataPoint', dataPoint);
})
.catch((error) => console.log(error));
}) // dataGroups.map
console.log("Final dataPoint", dataPoint);
const dataPoints = this.state.dataPoints.concat(dataPoint);
this.setState({ dataPoints });
}) // data.map
}) // fetch
.catch((error) => console.log(error));
}
render() {
console.log('Render Devices', this.state.devices);
console.log('Render dataPoints', this.state.dataPoints);
}][1]][1]
我希望最终组件的状态看起来像这样 或在渲染功能中-控制台日志记录应如下所示.
I am expecting a final component states that look like this or in render function - console logging should look like this.
devices = [{},{},{},{},{}...]
dataPoints = [[{},{},{},..], [{},{},{},..], [{},{},{},..], ....]
推荐答案
映射中的代码const dataPoints = this.state.dataPoints.concat(dataPoint)
始终会连接空数组,因为fetch是异步的,您的dataPoint
仅在api调用后会得到值.
your code const dataPoints = this.state.dataPoints.concat(dataPoint)
inside map will always concat empty array, because fetch is asynchronus and your dataPoint
will only get value after api calls.
其他问题是dataPoint.concat(data)
concat返回一个新数组,但是您没有存储可以使用dataPoint = dataPoint.concat(data)
或dataPoint = [...dataPoint, ...data]
Other issue is dataPoint.concat(data)
concat returns a new array but you are not storing the new array you can use dataPoint = dataPoint.concat(data)
or dataPoint = [...dataPoint, ...data]
您需要在const dataPoints = this.state.dataPoints.concat(dataPoint)
之前等待api调用的结果.您可以使用Promise.all
You need to wait for the result of api calls before const dataPoints = this.state.dataPoints.concat(dataPoint)
. You can use Promise.all
import React, { Component } from 'react';
import './App.css';
import Sensors from './iot/Sensors';
class App extends Component {
constructor (props) {
super (props);
this.state = {
status: 'disconnected',
devices: [],
dataPoints: []
};
}
componentDidMount() {
// Get Zigbee devices
fetch('http://localhost:3000/ssapi/zb/dev')
.then((res) => res.json())
.then((data) => {
this.setState({
devices : data
})
//Using forEach instead of map because we don't need the return of map
data.forEach((device) => {
const urls = JSON.parse(device.metadata).dataGroups.map((datagroup) =>
'http://localhost:3000/ssapi/zb/dev/' + device.id + '/ldev/' + datagroup.ldevKey + '/data/' + datagroup.dpKey) // dataGroups.map
Promise.all(urls.map(fetch))
.then(responses =>
Promise.all(responses.map(res => res.json()))
)
.then((data) =>{
//This data will be array of responses of all fetch fired
//destructuring response in array
const dataPoint = data.reduce((acc, curr)=> acc.concat(curr),[])
const dataPoints = this.state.dataPoints.concat(dataPoint)
console.log('All Data', data);
console.log('Inside dataPoint', dataPoint);
this.setState({ dataPoints });
})
.catch((error) => console.log(error));
}) // data.map
}) // fetch
.catch((error) => console.log(error));
}
render() {
console.log('Render Devices', this.state.devices);
console.log('Render dataPoints', this.state.dataPoints);
}
这篇关于如何在componentDidMount React中进一步完成之前完全完成获取数据并将其分配给组件状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!