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

React+MUI表格排序报错‘Data is not iterable’求助

解决React + MUI表格排序时的"Data is not iterable"错误

问题根源

你遇到的Data is not iterable错误,核心原因是将API返回的整个对象存入了data状态,而非其中的results数组。RandomUser API返回的结构是{ results: [...用户数组...], info: ... },当你在sorting函数中尝试用[...data]展开这个对象时,对象不是可迭代类型,因此抛出错误。

具体修复步骤

1. 修正API数据的存储逻辑

在useEffect的fetch回调中,仅将data.results存入状态:

useEffect(()=>{
    fetch('https://randomuser.me/api/?results=30')
    .then((response) => response.json())
    .then((apiData) => {
        setData(apiData.results); // 存储用户数组而非整个API响应对象
    });
}, []);

2. 修复排序函数逻辑

现在data是用户数组,[...data]可正常展开。同时针对嵌套属性(姓名、城市)调整排序逻辑:

const sorting=(col)=>{
    if(order==='asc'){
        let sorted;
        // 处理嵌套属性排序
        if(col === 'fullname'){
            sorted = [...data].sort((a,b) => {
                const nameA = `${a.name.first} ${a.name.last}`.toLowerCase();
                const nameB = `${b.name.first} ${b.name.last}`.toLowerCase();
                return nameA > nameB ? 1 : -1;
            });
        } else if(col === 'city'){
            sorted = [...data].sort((a,b) => {
                const cityA = a.location.city.toLowerCase();
                const cityB = b.location.city.toLowerCase();
                return cityA > cityB ? 1 : -1;
            });
        } else {
            sorted = [...data].sort((a,b) => 
                a[col].toLowerCase() > b[col].toLowerCase() ? 1 : -1
            );
        }
        setData(sorted);
        setOrder('dsc');
    } else if(order==='dsc'){ // 用else if避免同时执行两个分支
        let sorted;
        if(col === 'fullname'){
            sorted = [...data].sort((a,b) => {
                const nameA = `${a.name.first} ${a.name.last}`.toLowerCase();
                const nameB = `${b.name.first} ${b.name.last}`.toLowerCase();
                return nameA < nameB ? 1 : -1;
            });
        } else if(col === 'city'){
            sorted = [...data].sort((a,b) => {
                const cityA = a.location.city.toLowerCase();
                const cityB = b.location.city.toLowerCase();
                return cityA < cityB ? 1 : -1;
            });
        } else {
            sorted = [...data].sort((a,b) => 
                a[col].toLowerCase() < b[col].toLowerCase() ? 1 : -1
            );
        }
        setData(sorted);
        setOrder('asc');
    }
}

3. 完善表头的排序绑定

给所有列添加点击事件,并通过TableSortLabel展示当前排序方向:

<TableHead>
    <TableRow sx={{'& .MuiTableCell-root':{backgroundColor:"rgb(120, 169, 233)", border: "1px solid white", color: 'white'}}}
        <TableCell onClick={()=>sorting("fullname")} align="center">
            <TableSortLabel active={true} direction={order}>Fullname</TableSortLabel>
        </TableCell>
        <TableCell onClick={()=>sorting("email")} align="center">
            <TableSortLabel active={true} direction={order}>E-Mail</TableSortLabel>
        </TableCell>
        <TableCell onClick={()=>sorting("nat")} align="center">
            <TableSortLabel active={true} direction={order}>Nationality</TableSortLabel>
        </TableCell>
        <TableCell onClick={()=>sorting("city")} align="center">
            <TableSortLabel active={true} direction={order}>City</TableSortLabel>
        </TableCell>
    </TableRow>
</TableHead>

4. 修复分页组件的计数逻辑

TablePagination的count应使用data.length而非空数组rows.length:

<TablePagination
    rowsPerPageOptions={[10, 25, 100]}
    component="div"
    count={data.length} // 改为用户数组的长度
    rowsPerPage={rowsPerPage}
    page={page}
    onPageChange={handleChangePage}
    onRowsPerPageChange={handleChangeRowsPerPage}
/>

5. 优化表格渲染逻辑

初始data是空数组,可直接调用slice(),无需可选链:

{data.slice(page*rowsPerPage, page*rowsPerPage+rowsPerPage).filter((val)=>{
    if(searchTerm=== "") return val;
    const term = searchTerm.toLowerCase();
    return val.nat.toLowerCase().includes(term) 
        || val.email.toLowerCase().includes(term) 
        || val.location.city.toLowerCase().includes(term);
}).map((user,index) => (
    <TableRow key={index} sx={{'& .MuiTableCell-root':{backgroundColor: 'rgba(54, 96, 129, 0.241)', height: '3rem'}}}
        <TableCell align="center" component="th" scope="row">
            {`${user.name.first} ${user.name.last}`}
        </TableCell>
        <TableCell align="center">{user.email}</TableCell>
        <TableCell align="center">{user.nat}</TableCell>
        <TableCell align="center">{user.location.city}</TableCell>
    </TableRow>
))}

额外优化建议

  • 将排序状态拆分为orderBy(当前排序列)和orderDirection(升序/降序),避免切换排序时所有列同步变化
  • 提取排序逻辑为独立函数,提升代码可读性和复用性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:05:22