React页面刷新后变量无法正确填充,热重载时正常的问题求助
React页面刷新后变量无法正确填充,热重载时正常的问题求助
嘿,我来帮你拆解下这个问题的根源,以及对应的解决方案~
核心问题分析
你遇到的情况主要有两个关键原因:
React状态更新的异步特性
你在调用setCategorie(estratto)之后立刻console.log(categorie),这时候React还没完成状态更新,所以打印的还是初始的空数组。React的useState更新是异步批量处理的,不会立即改变状态值。两个Fetch请求并行执行,存在依赖关系却未同步
你的两个fetch是同时发起的:第二个请求(获取transazioni)需要用到第一个请求设置的categorie状态,但刷新页面时,categorie初始是空数组,第二个请求执行时,第一个请求还没完成状态更新,导致new Statistiche(categorie[0], categorie[1])拿到的是undefined,自然后续的统计数据无法正确生成。而热重载时,categorie已经缓存了之前的状态值,所以能正常工作。
解决方案
我们可以通过让请求串行执行+利用useEffect监听状态变化来修复这个问题,推荐用async/await让代码逻辑更清晰:
修改后的useEffect代码:
const [mesePerMese, setMesePerMese] = useState([]); const [annoPerAnno, setAnnoPerAnno] = useState([]); const [categorie, setCategorie] = useState([]); useEffect(() => { // 封装成异步函数 const fetchData = async () => { try { // 第一步:先获取并处理分类数据 const impostazioniRes = await fetch("http://localhost:3000/impostazioni"); const impostazioniData = await impostazioniRes.json(); const a = impostazioniData["data"]; const estratto = estraiCategorieEntrateUscite(a); setCategorie(estratto); // 第二步:依赖分类数据获取交易数据 const transazioniRes = await fetch("http://localhost:3000/transazioni"); const transazioniData = await transazioniRes.json(); const dati = transazioniData["data"]; const formattato = ISOitaliano(dati); const ordinato = ordinaDate(formattato); // 直接用处理好的estratto,不用等状态更新 let b = new Statistiche(estratto[0], estratto[1]); ordinato.map(rigo => { b.aggiungiTransazione(rigo); }); setMesePerMese(b.ottieniMesePerMese()); setAnnoPerAnno(b.ottieniAnnoPerAnno()); } catch (err) { // 别忘了处理错误 console.error("请求出错:", err); } }; fetchData(); }, []);
另外,如果你需要在categorie状态更新后做一些操作,可以添加一个监听categorie的useEffect:
useEffect(() => { // 当categorie有值时执行相关逻辑 if (categorie.length > 0) { console.log("更新后的categorie:", categorie); // 其他需要依赖categorie的操作也可以放在这里 } }, [categorie]);
补充说明
热重载时正常的原因是:React热重载会保留组件的状态,不会重置categorie为空数组,所以第二个请求执行时能拿到之前已经加载好的分类数据,自然能正常生成统计结果。
备注:内容来源于stack exchange,提问作者Simone
相关产品推荐
相关产品推荐

