React项目useEffect未触发问题求助:内部异步逻辑未执行
问题排查与解决方案
1. useEffect未执行的核心原因
你在useEffect回调里定义了一个async箭头函数,但没有调用它,函数体代码完全没执行,所以看不到console.log("hi")的输出。
修复方式
在useEffect内部定义async函数后立即调用,或者使用自执行异步函数:
useEffect(() => { // 定义并调用异步函数 const fetchData = async () => { console.log("hi"); // 后续API逻辑... }; fetchData(); }, []); // 或者用自执行写法 useEffect(() => { (async () => { console.log("hi"); // 后续API逻辑... })(); }, []);
2. 其他需修复的问题
(1)避免直接操作DOM,改用React useRef
你直接用document.getElementById获取按钮元素,组件挂载前DOM可能未渲染,会导致变量为null,调用hide时触发报错。改用useRef管理DOM引用:
import { useRef } from 'react'; // 组件内定义ref const btnAsRef = useRef<HTMLButtonElement>(null); const btnOpRef = useRef<HTMLButtonElement>(null); const btnWeRef = useRef<HTMLButtonElement>(null); const btnGeRef = useRef<HTMLButtonElement>(null); // JSX中绑定ref <button ref={btnAsRef} onClick={() => hide("Opdrachten")}>Opdrachten</button> <button ref={btnOpRef} onClick={() => hide("OpenAanvragen")}>OpenAanvragen</button> <!-- 其他按钮同理 --> // 修改hide函数 const hide = (ID: string) => { const x = document.getElementById(ID); if (!x) return; // 增加空值判断,避免报错 switch (ID) { case "Opdrachten": if (x.style.display === "none") { x.style.display = "block"; btnOpRef.current?.style.display = "none"; btnWeRef.current?.style.display = "none"; btnGeRef.current?.style.display = "none"; } else { x.style.display = "none"; } break; // 其他case逻辑同理修改 } };
(2)优化API调用性能,并行请求接口
当前API调用是串行执行(await逐个等待),改用Promise.all并行请求,减少整体等待时间:
const fetchData = async () => { console.log("hi"); try { // 并行请求所有需要的接口 const [completeAssignments, openResults, answeredResults, closedResults, assignments] = await Promise.all([ asyncCallApiByApiTag("getApiCompanyAanvragenGeslotenCompany"), asyncCallApiByApiTag("getApiCompanyRequestsOpenList"), asyncCallApiByApiTag("getApiCompanyRequestsAnsweredList"), asyncCallApiByApiTag("getApiCompanyRequestsClosedList"), asyncCallApiByApiTag("getApiCompanyAssignmentsList") ]); // 批量更新状态 setOpenRequests(openResults); setAnsweredRequests(answeredResults); setClosedRequests(closedResults); setCompleteAssignments(completeAssignments); setAssignments(assignments); } catch (error) { console.error("数据获取失败:", error); // 可添加错误提示逻辑 } };
(3)修复价格计算逻辑错误
你之前用map嵌套forEach,且每次循环都调用setState,会导致状态被多次覆盖,最终只保留最后一个元素的价格。正确做法是先计算总和,再一次性更新状态:
// 在fetchData函数内添加 let totalOmzet = 0; let totalVooruitzicht = 0; completeAssignments.forEach((item) => { const totalPrice = item.quotation.hoursPrice + item.quotation.materialPrice; if (item.assignment.completedRequest) { totalOmzet += totalPrice; } else { totalVooruitzicht += totalPrice; } }); setOmzet(totalOmzet); setVooruitzicht(totalVooruitzicht);
完整修改后的useEffect代码
useEffect(() => { const fetchData = async () => { console.log("hi"); try { const [completeAssignments, openResults, answeredResults, closedResults, assignments] = await Promise.all([ asyncCallApiByApiTag("getApiCompanyAanvragenGeslotenCompany"), asyncCallApiByApiTag("getApiCompanyRequestsOpenList"), asyncCallApiByApiTag("getApiCompanyRequestsAnsweredList"), asyncCallApiByApiTag("getApiCompanyRequestsClosedList"), asyncCallApiByApiTag("getApiCompanyAssignmentsList") ]); setOpenRequests(openResults); setAnsweredRequests(answeredResults); setClosedRequests(closedResults); setCompleteAssignments(completeAssignments); setAssignments(assignments); let totalOmzet = 0; let totalVooruitzicht = 0; completeAssignments.forEach((item) => { const price = item.quotation.hoursPrice + item.quotation.materialPrice; if (item.assignment.completedRequest) { totalOmzet += price; } else { totalVooruitzicht += price; } }); setOmzet(totalOmzet); setVooruitzicht(totalVooruitzicht); } catch (error) { console.error("数据获取失败:", error); } }; fetchData(); }, []);
内容的提问来源于stack exchange,提问作者NietTeDoen
相关产品推荐
相关产品推荐

