使用Chart.js实现折线图按月份排序,解决刷新渲染顺序随机问题
问题根因
- 你的MongoDB查询接口返回的统计数据没有显式按月份字段
_id做升序排序,MongoDB未指定排序规则的聚合查询返回结果顺序不固定,这是页面每次刷新图表顺序随机的核心原因。 - 你在循环中重复调用
setUserStats拼接数组的写法也存在冗余,多轮状态更新也可能带来不可控的顺序问题。
另外补充个细节问题:你定义的月份数组里Agu是拼写错误,正确的八月缩写是Aug。
修复后的代码
const Home = () => { const [userStats, setUserStats] = useState([]) const MONTHS = useMemo( () => [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', // 修正月份拼写错误 'Sep', 'Oct', 'Nov', 'Dec', ], [] ) useEffect(() => { const getStats = async () => { try { const res = await userRequest.get('/user/stats') // 先按月份id升序排序,再一次性处理成目标格式 const sortedStats = res.data .sort((a, b) => a._id - b._id) .map(item => ({ name: MONTHS[item._id - 1], 'Active User': item.total })) // 一次性更新状态,避免多次无效渲染 setUserStats(sortedStats) } catch (err) { console.error('获取用户统计数据失败:', err) } } getStats() }, [MONTHS]) console.log(userStats) return ( <div className="home"> <Featured /> <Chart data={userStats} title="user Analaytics" grid dataKey="Active User" /> <div className="homeWidgets"> <Widget /> <WidgetLg /> </div> </div> ) } export default Home
额外优化建议
- 可以直接在MongoDB的聚合查询里添加
$sort规则按_id升序返回数据,前端排序是兜底方案,后端排序能减少前端计算量。 - 建议给空catch块加上错误打印,方便后续接口异常时排查问题。
内容的提问来源于stack exchange,提问作者s_sldiblood
相关产品推荐
相关产品推荐

