React中Chart.js2与Material Table缩放无响应适配问题
你的响应式失效是三个写法问题叠加导致的:
- 布局层:MUI Grid使用不规范,额外套了未设置换行的横向flex容器包裹筛选器、图表、表格,小屏下元素不会自动换行堆叠;Card上写的
responsive: true是无效CSS属性,固定左右30px边距在移动端会挤占过多内容空间;部分容器未设置100%宽度,会被内部内容撑开溢出。 - 图表层:直接用
window.innerWidth/2给图表容器写死宽度,这个值仅在组件首次加载时计算一次,窗口尺寸变化时不会自动更新,刷新后正常只是因为重新初始化时取了当前窗口宽度,并非真响应式;且Chart.js响应式逻辑是依赖父容器尺寸的,直接绑定window宽度无法适配Card内部的实际可用空间。 - 表格层:MaterialTable未配置溢出滚动和紧凑模式,父容器宽度不足时表格会直接撑破外层Card,不会自动适配或滚动。
修复方案
1. 重构整体Grid布局
- 删掉包裹表单、环形图、表格的无换行flex容器,所有内容都放到MUI Grid的Item下,按断点分配宽度:大屏(md及以上)下表单占2列宽度、环形图占5列、汇总表格占5列;小屏(xs/sm)下每个元素都占12列宽度(整行),自动换行堆叠。
- 删掉Card上无效的
responsive: true样式,把固定的marginLeft:30、marginRight:30改成响应式边距,小屏自动缩小边距值,给所有外层容器添加width: 100%、boxSizing: border-box属性,避免内边距、边框把容器撑出父元素宽度。 - 包裹柱状图的Grid容器同样设置100%宽度,不要写固定的左、上外边距,用Grid自带的spacing属性控制间距。
2. 修正图表响应式逻辑
删掉两个图表组件外层容器写死的window.innerWidth / 2、window.innerHeight / 2样式,按Chart.js的响应式要求改容器:
- 容器宽度设为
width: '100%',设置最小高度保证图表不会被压得太扁,同时给图表配置加maintainAspectRatio: false让图表撑满容器高度。 - 图表内的标题文字用
clamp()设置响应式字号,避免小屏下标题过大溢出。
改完的环形图容器示例:
// HomeDoughChart.js <div style={{ width: '100%', minHeight: 350, position: 'relative', padding: '0 10px' }}> <h1 style={{ fontSize: 'clamp(1.2rem, 3vw, 2rem)', marginTop: 0 }}> Totale da riscuotere: {Intl.NumberFormat('it-IT', { style: 'currency', currency: 'EUR' }).format(props.chart.totaleDaPagare)} </h1> <Doughnut data={/* 保留原有数据配置 */} options={{ responsive: true, maintainAspectRatio: false }} style={{ marginTop: '20px' }} /> </div>
柱状图外层容器按完全相同的逻辑修改即可。
3. 给表格添加响应式配置
在MaterialTable的options参数中添加适配配置,同时给表格外层容器加横向溢出滚动:
<Grid item xs={12} md={5} style={{ marginTop: '50px', width: '100%', overflowX: 'auto' }} > <MaterialTable options={{ search: false, paging: false, sorting: false, // 新增响应式配置 tableLayout: 'auto', padding: 'dense', // 小屏下自动缩小单元格内边距 headerStyle: { whiteSpace: 'nowrap', padding: '8px 4px' }, cellStyle: { whiteSpace: 'nowrap', padding: '8px 4px' }, }} columns={/* 保留原有列配置 */} data={/* 保留原有数据配置 */} title="Consuntivo posizioni" /> </Grid>
配置后小屏下如果表格宽度超出容器,会自动出现横向滚动条,不会撑破外层Card布局。
额外问题修复
你当前写的handleYearChange、handleTributeChange事件存在React闭包问题,函数内拿到的dashboardfilter是上一次渲染的旧值,会导致筛选请求参数错误,建议把数据请求逻辑移到useEffect中监听dashboardfilter变化触发,不要在事件处理函数里直接拿state发请求。
内容的提问来源于stack exchange,提问作者64Bit1990
相关产品推荐
相关产品推荐

