
recharts图表在页面首次加载时不显示,仅在保存文件触发热重载后才出现,根本原因是状态更新异步性导致setmonthlydata(yearlydata[index])读取了过期的yearlydata(仍为初始空数组),应改为直接使用刚获取的data[index]。
这个问题本质是 React 状态更新的异步与不可变特性被误用所致。你在 getActivity 中调用 setYearlyData(data) 后,立即访问 yearlyData[index],但此时 yearlyData 仍是上一次渲染的值(如 [] 或 undefined),而非刚刚传入 setYearlyData 的新数据。React 不会同步修改 state 变量,而是将更新加入队列,并在下一次渲染时提供新值。
✅ 正确写法:使用当前获取的数据,而非依赖尚未更新的 state
const getActivity = async (index: number) => {
try {
const res = await api.get("/activity");
const data = res?.data || [];
setYearlyData(data);
// ✅ 关键修正:用刚拿到的 data[index],而非 yearlyData[index]
setMonthlyData(data[index] || []);
} catch (error) {
console.error("Failed to fetch activity data:", error);
setMonthlyData([]);
}
};
useEffect(() => {
getActivity(0);
}, []);⚠️ 额外建议:初始化 state 更健壮
避免因 yearlyData 初始值为 [] 导致静默失败(如 [][0] 得到 undefined),推荐显式初始化为 null 或带默认结构:
const [yearlyData, setYearlyData] = useState<{ name: string; user: number; guest: number }[]>([]);
const [monthlyData, setMonthlyData] = useState<{ name: string; user: number; guest: number }[]>([]);
// 或更严格地:
// const [yearlyData, setYearlyData] = useState(null as typeof initialData | null);同时,在渲染前增加数据校验,防止 Recharts 因空/无效 data 报错或白屏:
{monthlyData.length > 0 ? (
{/* 图表配置保持不变 */}
) : (
加载中...
)}? 调试技巧(快速定位类似问题)
在开发阶段,添加日志明确执行时序:
useEffect(() => {
console.log('[Render] yearlyData:', yearlyData, 'monthlyData:', monthlyData);
}, [yearlyData, monthlyData]);
const getActivity = async (index) => {
console.log('[Fetch Start]');
const res = await api.get("/activity");
const data = res?.data || [];
console.log('[Fetched Data]:', data);
setYearlyData(data);
console.log('[After setYearlyData] yearlyData (still old):', yearlyData); // ❌ 这里永远不是新值
setMonthlyData(data[index] || []); // ✅ 正确来源
};? 提示:Vite + SWC 环境下无特殊影响,该问题是通用 React 状态逻辑问题,与构建工具无关。
总结:永远不要在 setState 后立即读取同名 state 变量——它不会反映本次更新。始终基于当前作用域内已知的有效值(如 API 响应 data)派生后续状态,才能确保首屏正确渲染。










