【发布时间】:2021-05-05 00:20:57
【问题描述】:
我的顶级功能组件App 有一个承诺返回函数req(),它将被许多子组件调用。在内部,req() 更新App 的状态以显示它被调用(以及为什么),然后调用不同的返回承诺函数。这里是req():
//wrap all requests to track and display their progress
function req(func, args, waitCap, yayCap) {
//perform a callback on a given req, then update state
const withReq = (argId, callback) => {
let newReqs = state.reqList.map ( r => r); //copy the reqList
for (let reqIndex = 0; reqIndex < newReqs.length; reqIndex++) { //iterate through the list
if ((newReqs[reqIndex] && (newReqs[reqIndex].id === argId))) { //find a match
callback(newReqs[reqIndex]); //pass it to the callback
break;
}
}
setState( prevState => ({
...prevState,
reqList:newReqs,
}));
}
//kill a req and update state
const deleteReq = argId => {
let newReqs = state.reqList.filter( r => { //new reqList is the same list with no objects containing the argID
return r.id !== argId;
});
setState( prevState => ({
...prevState,
reqList:newReqs,
}));
}
//duplicate the req list
let newReqs = state.reqList.map( r => r );
const now = new Date(); //create a unique ID for this req for tracking
const reqId = [
now.getFullYear(),
String(now.getMonth()+1).padStart(2,"0"),
String(now.getDate()).padStart(2,"0"),
String(now.getHours()).padStart(2,"0"),
String(now.getMinutes()).padStart(2,"0"),
String(now.getSeconds()).padStart(2,"0"),
String(Math.floor(Math.random()*10000)).padStart(4,"0"),
].join("");
newReqs.push({ //add the new req to the new reqList
status:"waiting",
caption:waitCap,
id:reqId,
});
setState( prevState => ({ //render the changed list of Reqs
...prevState,
reqList:newReqs,
}));
return ServerCalls[func](args)
.then((res)=>{
withReq(reqId, foundReq =>{ //update the req to show success
foundReq.status="success";
foundReq.caption=yayCap;
});
setTimeout(() => {
deleteReq(reqId); //remove it from display after 3 seconds
}, 3000);
return res;
})
.catch((err)=>{
withReq(reqId, foundReq =>{ //update the req to show failure
foundReq.status="failure";
foundReq.caption=foundReq.caption+" Failed!";
});
setTimeout(() => {
deleteReq(reqId); //remove it from display after 3 seconds
}, 3000);
throw err;
})
}
这里的问题是Promise.then() 和Promise.catch() 中的回调函数在状态的初始值上运行,而不是在回调执行时的值,由于范围。这不是类组件的问题,只是功能性的。
功能组件有没有办法从回调中读取其执行时状态?还是需要解决方法?
【问题讨论】:
标签: reactjs callback react-hooks