Javascript Can';t在componentDidMount React Native中发送请求
我在从componentDidMount()向后端发送请求时遇到问题。基本上,在渲染屏幕之前,我需要做两件事:Javascript Can';t在componentDidMount React Native中发送请求,javascript,reactjs,react-native,state,Javascript,Reactjs,React Native,State,我在从componentDidMount()向后端发送请求时遇到问题。基本上,在渲染屏幕之前,我需要做两件事: 从API调用获取数据并将其保存到状态 将获得的数据发送到后端,并从后端获取响应值 我在第一步中遇到的问题是setState()是异步的,即使我的数组在console.log()数组中不是空的(我在render()和componentDidUpdate function中看到它的元素),在componentDidMount()中它也将是空的。现在,问题是:在显示屏幕之前,我仍然需要将状态
this.state = {
ActivityItem: [],
}
componentDidMount() {
this.getDataFromKit(INTERVAL); //get data from library that does API calls
this.sendDataToServer(); //sending to backend
}
componentDidUpdate() {
console.log("componentDidUpdate ", this.state.ActivityItem) // here array is not empty
}
getDataFromKit(dateFrom) {
new Promise((resolve) => {
AppleKit.getSamples(dateFrom, (err, results) => {
if (err) {
return resolve([]);
}
const newData = results.map(item => {
return { ...item, name: "ItemAmount" };
});
this.setState({ ActivityItem: [...this.state.ActivityItem, ...newData] })
})
});
最后一点:
sendDataToServer() {
UserService.sendActivityData(this.state.ActivityItem).then(response => {
}).catch(error => {
console.log(error.response);
})
在这里,它如预期的那样工作:
<Button
title='send data!'
onPress={() => this.sendDataToServer()
} />
你必须等待承诺的解决。你需要这样的东西:
componentDidMount() {
this.getDataFromKit(INTERVAL).then(result => {
this.sendDataToServer(result); //sending to backend
}).catch(e => console.error);
}
您还可以更新其他获取数据的函数以返回数据:
getDataFromKit(dateFrom) {
return new Promise((resolve) => {
AppleKit.getSamples(dateFrom, (err, results) => {
if (err) return resolve([]);
const newData = results.map(item => {
return { ...item, name: "ItemAmount" };
});
const allData = [ ...this.state.ActivityItem, ...newData ];
this.setState({ ActivityItem: allData });
resolve(allData);
});
});
}
最后,您需要“sendData”函数不依赖于状态,而是获取传递给它的参数:
sendDataToServer(data) {
UserService.sendActivityData(data).then(response => {
// ... do response stuff
}).catch(error => {
console.log(error.response);
});
}
处理多个请求 如果请求不相互依赖:
componentDidMount() {
Promise.all([
promise1,
promise2,
promise3,
]).then(([ response1, response2, response3 ]) => {
// do stuff with your data
}).catch(e => console.error);
}
componentDidMount() {
let response1;
let response2;
let response3;
promise1().then(r => {
response1 = r;
return promise2(response1);
}).then(r => {
response2 = r;
return promise3(response2);
}).then(r => {
response3 = r;
// do stuff with response1, response2, and response3
}).catch(e => console.error);
}
如果请求确实相互依赖:
componentDidMount() {
Promise.all([
promise1,
promise2,
promise3,
]).then(([ response1, response2, response3 ]) => {
// do stuff with your data
}).catch(e => console.error);
}
componentDidMount() {
let response1;
let response2;
let response3;
promise1().then(r => {
response1 = r;
return promise2(response1);
}).then(r => {
response2 = r;
return promise3(response2);
}).then(r => {
response3 = r;
// do stuff with response1, response2, and response3
}).catch(e => console.error);
}
就您的更新而言,似乎您将异步请求包装到了另一个异步请求中。我只是把它锁起来,而不是包起来: 使initKit成为一个返回承诺的函数
function initKit() {
return new Promise((resolve, reject) => {
AppleKit.initKit(
KitPermissions.uploadBasicKitData(),
(err, results) => {
if (err) reject({ error: 'InitKit failed' });
else resolve({ data: results });
}
);
});
}
function getSamples() {
return new Promise((resolve) => {
AppleKit.getSamples(dateFrom, (err, results) => {
if (err) resolve([]); //rest is the same
else resolve({ data: results });
});
});
}
使get samples成为一个单独的函数,返回一个承诺
function initKit() {
return new Promise((resolve, reject) => {
AppleKit.initKit(
KitPermissions.uploadBasicKitData(),
(err, results) => {
if (err) reject({ error: 'InitKit failed' });
else resolve({ data: results });
}
);
});
}
function getSamples() {
return new Promise((resolve) => {
AppleKit.getSamples(dateFrom, (err, results) => {
if (err) resolve([]); //rest is the same
else resolve({ data: results });
});
});
}
链2背靠背承诺:如果initKit失败,它将进入。catch
块,而getSamples
将不会运行
componentDidMount() {
initKit().then(kit => {
return getSamples();
}).then(samples => {
// do stuff with samples
}).catch(e => console.log);
}
谢谢你的帮助,我想我现在意识到它应该如何工作了。但还有一点:如果我有两个APi请求,因此有两个承诺要返回,您会建议如何处理这些请求?谢谢您的帮助,您的方法工作得很好。最后一件事,如果我把承诺放在另一个街区里,我怎么能兑现呢?(我会更新问题)