You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI DataGrid中React状态更新后对应列未更新问题求助

解决Material-UI DataGrid列不随状态更新的问题

问题根源

  • 状态类型不一致:你初始化brandMap用的是new Map(),但更新时却转换成了普通对象({ ...prevState, ...data.data.reduce(...) }),这会导致后续brandMap[params.value]的访问逻辑异常,类型突变也可能干扰React的状态更新检测。
  • Columns未监听brandMap变化:你仅在user变化时通过useEffect生成并设置columns,当brandMap更新后,columns不会重新生成,renderCell里的brandMap还是闭包中保存的旧值,自然无法同步更新显示。

修复步骤

步骤1:统一状态类型

把brandMap统一为普通对象(更适配你的访问方式),初始化时用空对象:

const [brandMap, setBrandMap] = useState({});

步骤2:让Columns响应brandMap变化

不在useEffect里生成columns,直接在组件主体中定义,让它依赖brandMap。这样每次brandMap更新,columns都会重新创建,DataGrid就能拿到最新的渲染逻辑:

// 直接在组件内定义columns,而非useEffect中
const columns = [
  { 
    field: 'image', 
    headerName: '', 
    filterable: false, 
    renderCell: (params) => (
      <img src={params.value} style={{width: "100px", height: "100px"}}/>
    )
  },
  { field: 'name', headerName: 'Name', editable: true, filterOperators, flex: 1 },
  { field: 'sku', headerName: 'SKU', editable: true, filterOperators, flex: 1 },
  // ...其他列
  { 
    field: 'brand_id', 
    headerName: 'Brand', 
    editable: true, 
    flex: 1, 
    renderCell: (params) => (
      <Typography variant="body2" color="text.secondary" component="p" style={{color: 'purple'}} >
        {brandMap[params.value] ?? <CircularProgress size={20} />}
      </Typography>
    )
  },
  // ...其他列
];

// 原useEffect仅负责数据初始化
useEffect(() => {
  updateData(1);
  fetchBrands();
}, [user]);

步骤3:优化fetchBrands的状态更新逻辑

去掉await和then混合写法,保持代码简洁清晰:

async function fetchBrands() {
  const accessToken = await getToken();
  const response = await fetch("http://localhost:8000/auth/brands", {
    method: "GET",
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  });
  const data = await response.json();
  const newBrandMap = data.data.reduce((map, obj) => {
    map[obj.id] = obj.name;
    return map;
  }, {});
  // 合并新旧状态
  setBrandMap(prev => ({ ...prev, ...newBrandMap }));
}

额外说明

如果坚持使用Map类型,需调整访问和更新逻辑:

// 初始化
const [brandMap, setBrandMap] = useState(new Map());

// 更新逻辑
setBrandMap(prev => {
  const newMap = new Map(prev);
  data.data.forEach(obj => newMap.set(obj.id, obj.name));
  return newMap;
});

// renderCell中访问
{brandMap.get(params.value) ?? <CircularProgress size={20} />}

这种情况下同样要让columns依赖brandMap,确保状态更新时列的渲染逻辑同步更新。

内容的提问来源于stack exchange,提问作者Oze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:25:35