[英]React useEffect hook and Async/await own fetch data func?
[英]Async/await with sync func changing react state
我在 React 中遇到async
/ await
函數和更改狀態的問題。 這是我的異步函數,通過單擊按鈕觸發:
async startNewEntry() {
this.addIssue();
let issue_id;
console.log(this.state.timeEntry, "started_timeEntry")
if (this.state.timeEntry?.issue?.id) {
issue_id = this.state.timeEntry?.issue?.id;
} else {
issue_id = (await this.issueService.list()).data[0]?.id;
}
const { data } = await this.timeEntryService.create({
comments: this.state.timeEntry.comments,
issue_id,
spent_on: moment(new Date()).format("YYYY-MM-DD"),
hours: 0.01,
activity_id: this.localStorageService.get("defaultActivityId")
});
在這個函數中,我使用this.addIssue
,它使用this.createIssue
,它改變了我的類組件狀態:
addIssue() {
this.projectService.list([]).then(response => {
response.data = response.data.filter((x: any) => x.status === 1);
this.setState(
{
activeProjects: response.data
},
() => {
this.createIssue();
}
);
});
}
createIssue() {
this.issueAddService
.create({
project_id: this.state.activeProjects[0].id,
tracker_id: trakerId,
priority_id: priorityId,
subject: this.state.timeEntry.comments,
description: this.state.timeEntry.comments
})
.then(response => {
let timeEntry = this.state.timeEntry;
timeEntry.issue = response.data;
this.setState({
timeEntry
});
})
.catch(error => {
console.log("error", error);
});
}
如您所見,在我的 async 函數中,我擁有新的 State,但實際上 async 函數在我的this.addIssue
函數之前工作。 我知道這個問題可能有點奇怪,但先謝謝你!!
如果您希望startNewEntry
等到addIssue
完成其工作后才addIssue
工作,您需要:
addIssue
在完成工作后返回一個承諾,並且await
: await this.addIssue();
如果您需要startNewEntry
來查看更新的狀態,則需要從狀態完成處理程序回調中實現addIssue
的承諾,如下所示:
addIssue() {
// *** Return the promise chain to the caller
return this.projectService.list([]).then(response => {
response.data = response.data.filter((x: any) => x.status === 1);
// *** Create a new promise
return new Promise(resolve => {
this.setState(
{
activeProjects: response.data
},
() => {
this.createIssue();
resolve(); // *** Fulfill the promise
}
);
});
});
}
通常, new Promise
是一種反模式,尤其是當您有另一個可以鏈接的new Promise
時。 但是在這種情況下,由於您需要等待來自setState
的回調(未啟用 promise),因此是合適的。 (
我不是 React 專家,但我不完全理解為什么有很多setState
調用散布在這個地方。
如果您將setState
留在函數的末尾,那么您可能不需要擔心對它的異步調用正確排序(盡管另一個答案確實顯示了如何實現)。
也許調用一次可能會使代碼更清晰。 歡迎指正。。。
async startNewEntry() {
const activeProjects = await fetchActiveProjects()
const issue = await this.createIssue()
const timeEntry = await createTimeEntry({ issue, comments: this.state.timeEntry.comments })
this.setState({ activeProjects, issue, timeEntry })
}
async fetchActiveProjects() {
const { data } = await this.projectService.list([])
return data.filter(({ status }) => status === 1)
}
async createIssue() {
const { data } = await this.issueAddService.create({
project_id: this.state.activeProjects[0].id,
tracker_id: trakerId,
priority_id: priorityId,
subject: this.state.timeEntry.comments,
description: this.state.timeEntry.comments
})
return data
}
async createTimeEntry({issue, comments}) {
const { data } = await this.timeEntryService.create({
comments,
issue_id: issue?.id || (await this.issueService.list()).data[0]?.id,
spent_on: moment(new Date()).format("YYYY-MM-DD"),
hours: 0.01,
activity_id: this.localStorageService.get("defaultActivityId")
})
return data
}
您可以通過並行化前兩個異步調用來進一步加快速度:
async startNewEntry() {
const [activeProjects, issue] =
await Promise.all([fetchActiveProjects(), this.createIssue()])
const timeEntry = await createTimeEntry({ issue, comments: this.state.timeEntry.comments })
this.setState({ activeProjects, issue, timeEntry })
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.