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

MUI Data Grid列头国际化切换失效问题求助

MUI Data Grid 列头本地化语言切换不更新的解决办法

问题说明

用MUI Data Grid构建表格做i18n本地化时,列头配置是静态对象,初始化时调用i18next.t()生成翻译文本,但切换语言后,列头不会自动更新——因为静态数组只在模块加载时执行一次t(),语言变化后不会重新计算。

你的列配置代码

import { Box, Tooltip } from "@mui/material";
import {
  deliverTruckBulk,
  pickupTruckBulk,
} from "assets/img/statuses/statusImages";
import { dateComparator, localizeDate, localizeTime } from "helpers/helpers";
import i18next from "i18next";
import StatusIcon from "../../../../StatusIcon/StatusIcon";
import {
  OrderTableCaption,
  OrderTableText,
} from "../../../../Typography/OrderList";

export const OrderTableColumns = [
  {
    field: "shippingDate",
    headerName: "Requested Date",
    sortComparator: dateComparator,
    renderCell: (params) => (
      <Box>
        <OrderTableText sx={{ fontWeight: 500 }}>
          {localizeDate(params.value.date)}
        </OrderTableText>
        <OrderTableCaption>
          {`${localizeTime(params.value.startTime)} - ${localizeTime(
            params.value.endTime
          )}`}
        </OrderTableCaption>
      </Box>
    ),
    flex: 0,
  },
  {
    field: "po-order",
    headerName: i18next.t("order.orderNumber"),
    renderCell: (params) => (
      <Box>
        <OrderTableText>{params.value.customerReference}</OrderTableText>
        <OrderTableCaption>{params.value.orderNumber}</OrderTableCaption>
      </Box>
    ),
    flex: 1,
    sortable: false,
  },
  {
    field: "destination",
    headerName: "Destination",
    renderCell: (params) => (
      <Box sx={{ display: "flex", flexDirection: "column" }}>
        <OrderTableText>{params.value.siteName}</OrderTableText>
        <OrderTableCaption>{params.value.street}</OrderTableCaption>
      </Box>
    ),
    flex: 1,
    sortable: false,
  },
  {
    field: "material",
    headerName: "Material",
    renderCell: (params) => <OrderTableText>{params.value}</OrderTableText>,
    flex: 1,
    sortable: false,
  },
  {
    field: "ordered-delivered",
    headerName: "Ordered/Delivered",
    renderCell: ({ value }) => {
      const isShippingTypeCollect = value.shippingType === "collect";
      const shippingType = isShippingTypeCollect
        ? pickupTruckBulk
        : deliverTruckBulk;

      const tooltipTitle = `${
        isShippingTypeCollect ? "Pick-up" : "Delivery"
      } by bulk carrier`;

      return (
        <Box sx={{ display: "flex", columnGap: "5px" }}>
          <OrderTableText>
            {value.quantity} {i18next.t("capacityTons1")}
          </OrderTableText>
          <Tooltip title={tooltipTitle}>
            <img src={shippingType} alt={shippingType} width="24px" />
          </Tooltip>
        </Box>
      );
    },
    flex: 0,
    sortable: false,
  },
  {
    field: "status",
    headerName: i18next.t("order.orderStatus"),
    renderCell: (params) => <StatusIcon status={params.value} />,
    flex: 0,
    maxWidth: 60,
    sortable: false,
  },
];

解决方案

方案1:把列配置改成动态生成函数

放弃静态数组,改成返回列配置的函数,每次调用都会重新执行t()获取最新翻译。然后在表格组件中监听语言变化,触发重新生成列配置。

步骤1:修改列配置文件

import { Box, Tooltip } from "@mui/material";
import { deliverTruckBulk, pickupTruckBulk } from "assets/img/statuses/statusImages";
import { dateComparator, localizeDate, localizeTime } from "helpers/helpers";
import i18next from "i18next";
import StatusIcon from "../../../../StatusIcon/StatusIcon";
import { OrderTableCaption, OrderTableText } from "../../../../Typography/OrderList";

// 改成函数,每次调用都返回新的列配置数组
export const getOrderTableColumns = () => [
  {
    field: "shippingDate",
    // 把硬编码文本换成翻译键
    headerName: i18next.t("order.requestedDate"),
    sortComparator: dateComparator,
    renderCell: (params) => (
      <Box>
        <OrderTableText sx={{ fontWeight: 500 }}>
          {localizeDate(params.value.date)}
        </OrderTableText>
        <OrderTableCaption>
          `${localizeTime(params.value.startTime)} - ${localizeTime(params.value.endTime)}`
        </OrderTableCaption>
      </Box>
    ),
    flex: 0,
  },
  {
    field: "po-order",
    headerName: i18next.t("order.orderNumber"),
    renderCell: (params) => (
      <Box>
        <OrderTableText>{params.value.customerReference}</OrderTableText>
        <OrderTableCaption>{params.value.orderNumber}</OrderTableCaption>
      </Box>
    ),
    flex: 1,
    sortable: false,
  },
  {
    field: "destination",
    headerName: i18next.t("order.destination"),
    renderCell: (params) => (
      <Box sx={{ display: "flex", flexDirection: "column" }}>
        <OrderTableText>{params.value.siteName}</OrderTableText>
        <OrderTableCaption>{params.value.street}</OrderTableCaption>
      </Box>
    ),
    flex: 1,
    sortable: false,
  },
  {
    field: "material",
    headerName: i18next.t("order.material"),
    renderCell: (params) => <OrderTableText>{params.value}</OrderTableText>,
    flex: 1,
    sortable: false,
  },
  {
    field: "ordered-delivered",
    headerName: i18next.t("order.orderedDelivered"),
    renderCell: ({ value }) => {
      const isShippingTypeCollect = value.shippingType === "collect";
      const shippingType = isShippingTypeCollect
        ? pickupTruckBulk
        : deliverTruckBulk;

      // 替换硬编码tooltip文本
      const tooltipTitle = `${i18next.t(isShippingTypeCollect ? "order.pickup" : "order.delivery")} ${i18next.t("order.byBulkCarrier")}`;

      return (
        <Box sx={{ display: "flex", columnGap: "5px" }}>
          <OrderTableText>
            {value.quantity} {i18next.t("capacityTons1")}
          </OrderTableText>
          <Tooltip title={tooltipTitle}>
            <img src={shippingType} alt={shippingType} width="24px" />
          </Tooltip>
        </Box>
      );
    },
    flex: 0,
    sortable: false,
  },
  {
    field: "status",
    headerName: i18next.t("order.orderStatus"),
    renderCell: (params) => <StatusIcon status={params.value} />,
    flex: 0,
    maxWidth: 60,
    sortable: false,
  },
];

步骤2:在表格组件中监听语言变化

import { useEffect, useState } from "react";
import { DataGrid } from "@mui/x-data-grid";
import { getOrderTableColumns } from "./path-to-your-columns-file";
import i18next from "i18next";

const OrderTable = () => {
  // 初始化列配置
  const [columns, setColumns] = useState(getOrderTableColumns());

  useEffect(() => {
    // 监听i18n语言变化事件
    const handleLangChange = () => {
      // 重新生成列配置,触发更新
      setColumns(getOrderTableColumns());
    };

    // 绑定事件
    i18next.on("languageChanged", handleLangChange);
    // 组件卸载时解绑
    return () => i18next.off("languageChanged", handleLangChange);
  }, []);

  return <DataGrid columns={columns} rows={yourRowsData} {...otherProps} />;
};

export default OrderTable;

方案2:用headerRenderer渲染列头(推荐react-i18next用户)

MUI Data Grid支持用headerRenderer属性传入React组件来渲染列头,这样可以直接使用useTranslation钩子,自动响应语言变化。

步骤1:修改列配置(注意要在React组件内部定义,或者封装成组件)

import { useTranslation } from "react-i18next";
import { Box, Tooltip } from "@mui/material";
// 其他导入...

// 如果要在组件外部复用,封装成独立的列头组件
const OrderNumberHeader = () => {
  const { t } = useTranslation();
  return <span>{t("order.orderNumber")}</span>;
};

// 在React组件内部定义列配置
const OrderTable = () => {
  const { t } = useTranslation();

  const columns = [
    {
      field: "po-order",
      // 用headerRenderer代替headerName
      headerRenderer: () => <OrderNumberHeader />,
      renderCell: (params) => (
        <Box>
          <OrderTableText>{params.value.customerReference}</OrderTableText>
          <OrderTableCaption>{params.value.orderNumber}</OrderTableCaption>
        </Box>
      ),
      flex: 1,
      sortable: false,
    },
    // 其他列同理,比如:
    {
      field: "status",
      headerRenderer: () => <span>{t("order.orderStatus")}</span>,
      renderCell: (params) => <StatusIcon status={params.value} />,
      flex: 0,
      maxWidth: 60,
      sortable: false,
    },
    // 剩余列配置...
  ];

  return <DataGrid columns={columns} rows={yourRowsData} />;
};

这种方式下,只要useTranslation钩子感知到语言变化,列头组件就会自动重新渲染,更新翻译文本。

关键注意点

  1. 所有硬编码的文本(比如原来的"Requested Date")都要替换成对应的翻译键,确保全量本地化。
  2. 如果使用react-i18next,优先用useTranslation钩子,它会自动订阅语言变化,比直接调用i18next.t()更省心。
  3. renderCell里的动态文本(比如tooltip)也要换成翻译键,避免遗漏本地化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:04:58