React中合并对象数组并按唯一Email渲染表格的问题
问题
从API获取两个对象数组(候选人数据Candidates和职位空缺数据Jobopenings),尝试在表格中渲染时,用扩展运算符合并数组后出现同一Email对应多行的重复渲染问题。需要实现按唯一Email合并数组,使每个Email对应表格一行。
问题原因
直接用[...data.Candidates, ...data.Jobopenings]只是简单拼接两个数组,导致同一Email的条目(比如Pradeep的候选人数据和职位空缺数据)会被分别保留,渲染时自然出现重复行。
解决方案
通过按Email分组合并属性的方式处理数组:用一个中间对象存储每个Email对应的合并数据,遍历两个数组时将相同Email的属性合并,最后将对象转为数组即可得到去重且合并后的数据集。同时要修正表格的HTML结构(避免每个循环生成独立的<tbody>)。
修改后的代码
export default function App() { const [allData, setAllData] = useState([]); let data = { status: 'success', Candidates: [ { Recruiter: 'Pradeep', Email: 'Pradeep@gmail.com', Total: 11, Hired: 2, interviewscheduled: 0, clientsubmitted: 1, Withdrawn: 0, Onhold: 5, inprocess: 0, Rejected: 1, Available: 0, tobeupdated: 2, }, { Recruiter: 'Sudhir', Email: 'sudhir@gmail.com', Total: 6, Hired: 1, interviewscheduled: 0, clientsubmitted: 1, Withdrawn: 0, Onhold: 1, inprocess: 0, Rejected: 0, Available: 0, tobeupdated: 3, }, ], Jobopenings: [ { Recruiter: 'Pradeep', Email: 'Pradeep@gmail.com', jobopeningTotal: 4, }, { Recruiter: 'Sudhir', Email: 'sudhir@gmail.com', jobopeningTotal: 7, }, { Recruiter: 'Marry Scott', Email: 'marrys@hsc.com', jobopeningTotal: 1, }, ], }; useEffect(() => { // 创建映射对象,用Email作为唯一键 const mergedMap = {}; // 先处理候选人数据,初始化映射 data.Candidates.forEach(item => { mergedMap[item.Email] = { ...item }; }); // 处理职位空缺数据,合并到已有条目或新增 data.Jobopenings.forEach(item => { if (mergedMap[item.Email]) { // 合并属性,职位数据会覆盖候选人中同名属性(这里没有冲突) mergedMap[item.Email] = { ...mergedMap[item.Email], ...item }; } else { // 新增没有候选人数据的职位条目 mergedMap[item.Email] = { ...item }; } }); // 将映射转为数组 const mergedData = Object.values(mergedMap); setAllData(mergedData); }, []); return ( <div> <table className="table table-bordered rounded"> <thead> <tr> <th scope="col">Recruiter Name</th> <th scope="col">Job Openings</th> <th scope="col">Hired Candidates</th> <th scope="col">Candidates</th> <th scope="col">Clients' Submissions</th> <th scope="col">Interviews Scheduled</th> </tr> </thead> <tbody> {allData?.map((eachItem) => { return ( <tr key={eachItem.Email}> <td scope="row">{eachItem.Recruiter}</td> <td>{eachItem.jobopeningTotal || 0}</td> <td>{eachItem.Hired || 0}</td> <td>{eachItem.Total || 0}</td> <td>{eachItem.clientsubmitted || 0}</td> <td>{eachItem.interviewscheduled || 0}</td> </tr> ); })} </tbody> </table> </div> ); }
关键说明
- 合并逻辑:用
mergedMap对象存储每个Email的合并数据,先存入候选人数据,再遍历职位数据合并到对应条目,确保同一Email只保留一条合并后的数据。 - HTML结构修正:将
<tbody>从map循环中移出,避免生成多个tbody标签,符合标准表格结构。 - 默认值处理:在渲染表格单元格时添加
|| 0,避免没有对应属性时显示undefined,优化视觉效果。
内容的提问来源于stack exchange,提问作者user19614803
相关产品推荐
相关产品推荐

