在Next.js中如何合并两个数组并替换字段值?
解决思路及代码实现
要把offers里的product_id替换成对应产品名称,核心是先把products转成ID到名称的映射表(查找效率更高),再遍历offers做字段替换。直接上代码方案:
步骤1:构建产品ID-名称映射表
用useMemo缓存映射结果,避免每次渲染都重复生成:
// 将products数组转为 { productId: productName } 的对象映射 const productMap = React.useMemo(() => { if (!products) return {}; return products.reduce((map, product) => { map[product.id] = product.name; return map; }, {}); }, [products]);
步骤2:处理offers数据
同样用useMemo,仅当offers或productMap变化时重新处理数据:
// 替换offers中的product_id为对应产品名称 const processedOffers = React.useMemo(() => { if (!offers || !productMap) return []; return offers.map(offer => ({ ...offer, // 新增product_name字段,找不到对应产品时显示兜底文本 product_name: productMap[offer.product_id] || `未匹配产品(${offer.product_id})` // 若要直接替换原product_id字段,可改成:product_id: productMap[offer.product_id] || offer.product_id })); }, [offers, productMap]);
步骤3:渲染处理后的数据
先判断加载状态,避免初始null值导致报错:
return ( <div> {!processedOffers.length ? ( <p>加载中...</p> ) : ( <table border="1"> <thead> <tr> <th>优惠ID</th> <th>优惠名称</th> <th>关联产品</th> </tr> </thead> <tbody> {processedOffers.map(offer => ( <tr key={offer.id}> <td>{offer.id}</td> <td>{offer.name}</td> <td>{offer.product_name}</td> </tr> ))} </tbody> </table> )} </div> );
完整代码整合
把以上部分和你原有的请求代码结合,还做了并行请求优化:
const OfferTable = () => { const [offers, setOffers] = React.useState(null); const [products, setProducts] = React.useState(null); React.useEffect(() => { // 并行请求两个API,提升加载速度 Promise.all([ fetch(`http://localhost:3000/api/offers`).then(res => res.json()), fetch(`http://localhost:3000/api/products`).then(res => res.json()) ]).then(([offersRes, productsRes]) => { setOffers(offersRes.data); setProducts(productsRes.data); }).catch(err => { console.error('数据加载失败:', err); }); }, []); const productMap = React.useMemo(() => { if (!products) return {}; return products.reduce((map, product) => { map[product.id] = product.name; return map; }, {}); }, [products]); const processedOffers = React.useMemo(() => { if (!offers || !productMap) return []; return offers.map(offer => ({ ...offer, product_name: productMap[offer.product_id] || `未匹配产品(${offer.product_id})` })); }, [offers, productMap]); return ( <div> {!processedOffers.length ? ( <p>加载中...</p> ) : ( <table border="1"> <thead> <tr> <th>优惠ID</th> <th>优惠名称</th> <th>关联产品</th> </tr> </thead> <tbody> {processedOffers.map(offer => ( <tr key={offer.id}> <td>{offer.id}</td> <td>{offer.name}</td> <td>{offer.product_name}</td> </tr> ))} </tbody> </table> )} </div> ); }; export default OfferTable;
额外优化说明
- 用
Promise.all并行发起两个请求,比单独两次fetch更快拿到完整数据 - 增加错误捕获,避免请求失败导致页面无响应
- 处理产品匹配失败的边界情况,显示友好提示文本
内容的提问来源于stack exchange,提问作者ktzy13
相关产品推荐
相关产品推荐

