React自定义Hook本地正常,云端构建后数据渲染失败求助
React 项目云端部署后数据不显示的问题排查与修复
核心问题分析
- 异步循环未正确等待:
forEach中使用async/await无法等待所有请求完成,导致setRegistersQualidade在请求还未返回时就执行,此时数组还是初始状态。本地环境请求速度快,偶然能拿到更新后的数据,但云端网络延迟会暴露这个问题。 - 直接修改全局导出的数组:
listUrlGestaoQualidade是全局导出的常量数组,直接修改它的属性不会触发 React 的状态更新,生产构建中甚至可能因优化导致修改不生效。 - 外部获取的变量未实时更新:
tokenUser、licenca、projeto在 Hook 外部初始化,组件挂载后这些值变化时,Hook 不会重新获取最新值,可能导致请求参数错误。 - 错误未捕获:请求的
catch块为空,云端请求出错时无法排查问题,也不会有任何反馈。
修复方案
修改后的自定义 Hook 代码
// hooks/useGetQualidade.js import { useCallback, useContext } from "react"; import { GlobalState } from "../store"; import { listUrlGestaoQualidade } from "../json/listRequests"; import api from "../services/api"; export const useGetQualidade = () => { const { setRegistersQualidade } = useContext(GlobalState); const executeGetQualidade = useCallback(async () => { // 实时获取本地存储的最新值 const tokenUser = localStorage.getItem('@app-token'); const licenca = localStorage.getItem('@app-licenca'); const projeto = localStorage.getItem('@projeto'); const params = `?filters[licenca][$eq]=${licenca}&filters[numero_projeto][$eq]=${projeto}`; // 创建数组副本,避免修改原始全局常量 const updatedList = [...listUrlGestaoQualidade]; // 使用 Promise.all 等待所有请求完成 await Promise.all(updatedList.map(async (request, index) => { try { const res = await api.get(request.url + params, { headers: { Authorization: `Bearer ${tokenUser}` } }); if (request.name === 'Pré - Qualificação de solda por Termorusão') { const statusAprovado = []; const statusReprovado = []; if (res.data.data.length > 0) { res.data.data.forEach(status => { if (status.attributes.status_deslocamento === 'Aprovado' && status.attributes.status_cisalhamento === 'Aprovado') { statusAprovado.push('Aprovado'); } else { statusReprovado.push('Reprovado'); } }); // 生成新对象更新副本,保证状态可追踪 updatedList[index] = { ...updatedList[index], qtd: res.data.data.length, aprovado: statusAprovado.length, reprovado: statusReprovado.length, aproveitamento: (statusAprovado.length / res.data.data.length * 100).toFixed(2) }; } } } catch (err) { console.error(`请求 ${request.url} 失败:`, err); // 出错时设置默认值,避免数据缺失 updatedList[index] = { ...updatedList[index], qtd: 0, aprovado: 0, reprovado: 0, aproveitamento: 0 }; } })); setRegistersQualidade(updatedList); }, [setRegistersQualidade]); return { executeGetQualidade }; }
额外检查点
- 云端跨域配置:确认后端 API 已将云端前端域名加入跨域允许列表,本地开发的代理配置在云端不生效。
- 本地存储可用性:部分云端环境可能限制 localStorage 访问,可在组件中添加检查:
useEffect(() => { try { localStorage.getItem('@app-token'); } catch (err) { console.error('本地存储不可用:', err); } executeGetQualidade(); }, [executeGetQualidade]); - Context 初始值:确保
GlobalState中registersQualidade的初始值为数组(如[]),避免map时出现空值错误。
内容的提问来源于stack exchange,提问作者Ricardo Teixeira
相关产品推荐
相关产品推荐

