Recharts图表首次加载不显示,仅Ctrl+S重绘后显示的解决方法
问题
使用Recharts创建LineChart,通过axios从本地json-server托管的db.json拉取数据。页面首次加载或刷新时图表不显示,只有保存文件触发重绘后才会显示。
环境版本:
- react@18.2.0
- vite@4.4.3
- recharts@2.7.2
图表代码:
<ResponsiveContainer width="100%" height={270}> <LineChart width={600} height={300} data={monthlyData} margin={{ left: -20, }} > <CartesianGrid vertical={false} /> <Tooltip /> <XAxis axisLine={false} dataKey="name" tickSize={0} tickMargin={10} /> <YAxis axisLine={false} domain={[0, maxY]} tickCount={maxY / 100 + 1} tickSize={0} tickMargin={10} /> <Line type="monotone" dataKey="user" strokeWidth={2} stroke="#9BDD7C" dot={false} /> <Line type="monotone" dataKey="guest" strokeWidth={2} stroke="#E9A0A0" dot={false} /> </LineChart> </ResponsiveContainer>
数据获取代码:
const getActivity = async (index) => { const res = await api.get("/activity"); const data = res?.data; setYearlyData(data); setMonthlyData(yearlyData[index]); }; useEffect(() => { getActivity(0); }, []);
解决方案
问题出在getActivity函数的状态更新逻辑:React的setState是异步操作,调用setYearlyData(data)后,yearlyData不会立刻更新为新值。此时执行setMonthlyData(yearlyData[index]),实际用到的还是更新前的yearlyData(大概率是初始空值/undefined),导致monthlyData没有有效数据,图表无法渲染。
修改getActivity函数,直接使用刚获取的data来设置monthlyData,而非依赖未更新的状态:
const getActivity = async (index) => { const res = await api.get("/activity"); const data = res?.data; setYearlyData(data); // 直接用接口返回的data,避免依赖异步更新的state setMonthlyData(data[index]); }; useEffect(() => { getActivity(0); }, []);
额外可以做两个优化避免边界问题:
- 给
monthlyData设置初始值(比如空数组[]),防止图表因数据为undefined报错 - 渲染图表前判断数据是否存在,添加加载状态:
{monthlyData ? ( <ResponsiveContainer width="100%" height={270}> {/* 图表内容 */} </ResponsiveContainer> ) : ( <div>加载中...</div> )}
内容的提问来源于stack exchange,提问作者Stowaway4331
相关产品推荐
相关产品推荐

