mui-datatables对象类型列自定义渲染后排序失效问题求助
问题根因
mui-datatables的默认排序逻辑是直接读取列配置中name字段对应的数据源属性进行比较,你当前两列的name都绑定了details整个对象,JavaScript中两个对象直接对比大小不会得到预期结果,且两列绑定同一个数据源字段也会导致排序逻辑冲突,这是排序失效的核心原因。
解决方案1:使用sortCompare自定义排序逻辑(无需改动原数据)
直接在对应列的options中新增sortCompare配置,指定用对象下的对应属性做排序对比即可。修改后的列配置参考:
const columns = [ { name: "details", label: "Name", options: { customBodyRender: (value: any, tableMeta: any, updateValue: any) => { return value?.Name; }, sort: true, filter: true, // 新增自定义排序逻辑,按details下的Name属性排序 sortCompare: (obj1: any, obj2: any) => { const name1 = obj1.details?.Name || ''; const name2 = obj2.details?.Name || ''; return name1.localeCompare(name2); }, setCellProps: () => ({ align: "center", }), setCellHeaderProps: (value: any) => ({ className: "centeredHeaderCell", }), }, }, { name: "details", label: "Score", options: { filter: true, sort: true, customBodyRender: (value: any, tableMeta: any, updateValue: any) => { return value?.Score; }, // 新增自定义排序逻辑,按details下的Score属性排序 sortCompare: (obj1: any, obj2: any) => { const score1 = obj1.details?.Score || ''; const score2 = obj2.details?.Score || ''; // 如果是纯数值范围可提取数值做差值比较,字符串排序用localeCompare即可 return score1.localeCompare(score2); }, setCellProps: () => ({ align: "center", }), setCellHeaderProps: (value: any) => ({ className: "centeredHeaderCell", }), }, } ]
解决方案2:预处理数据拍平嵌套属性(适合多场景复用)
如果不想每列都写自定义排序逻辑,可以在拿到原始数据后先把嵌套的details下的属性拍平到根层级,列配置直接绑定拍平后的字段,默认排序就能正常生效。
拍平数据示例代码:
// 原始数据预处理逻辑 const formatRawData = (rawData) => { return rawData.map(item => ({ ...item, detailName: item.details?.Name || '', detailScore: item.details?.Score || '' })) } // 状态初始化时用处理后的数据 const [data, setData] = useState(formatRawData(你的原始数据源))
对应修改列配置,直接绑定拍平后的字段即可:
const columns = [ { name: "detailName", // 直接绑定拍平后的属性 label: "Name", options: { sort: true, filter: true, setCellProps: () => ({ align: "center" }), setCellHeaderProps: () => ({ className: "centeredHeaderCell" }), }, }, { name: "detailScore", // 直接绑定拍平后的属性 label: "Score", options: { sort: true, filter: true, setCellProps: () => ({ align: "center" }), setCellHeaderProps: () => ({ className: "centeredHeaderCell" }), }, } ]
提示:如果排序字段是数值类型,需要先把字段值转为
Number类型再做差值比较,不要用字符串的localeCompare方法,避免出现10 < 2的错误排序结果。
内容的提问来源于stack exchange,提问作者Y_T
相关产品推荐
相关产品推荐

