如何合并两个React Hook输出并对比展示为表格
解决方案
1. 合并数据请求逻辑
把两个Axios请求放到同一个useEffect里,用Promise.all并行发起,这样就能正常使用purchase_date参数(不管是从props还是组件状态里获取)。示例代码:
import { useState, useEffect } from 'react'; import axios from 'axios'; const PurchaseComparison = ({ purchaseDate }) => { const [currentData, setCurrentData] = useState([]); const [lastYearData, setLastYearData] = useState([]); const [comparisonData, setComparisonData] = useState([]); useEffect(() => { // 获取当前采购数据 const fetchCurrentData = async () => { const res = await axios.get(`/api/current-purchases?date=${purchaseDate}`); return res.data; }; // 获取去年同期采购数据(自动计算去年日期) const fetchLastYearData = async () => { const lastYearDate = new Date(purchaseDate); lastYearDate.setFullYear(lastYearDate.getFullYear() - 1); const formattedDate = lastYearDate.toISOString().split('T')[0]; const res = await axios.get(`/api/last-year-purchases?date=${formattedDate}`); return res.data; }; // 并行发起两个请求 const fetchAll = async () => { try { const [current, lastYear] = await Promise.all([ fetchCurrentData(), fetchLastYearData() ]); setCurrentData(current); setLastYearData(lastYear); } catch (err) { console.error('数据获取失败:', err); } }; fetchAll(); }, [purchaseDate]); // 日期变化时自动重新请求
2. 合并对比数据
监听当前和去年数据的变化,把两组数据按ID匹配,生成带对比字段的数组:
useEffect(() => { // 把去年数据转成ID为键的对象,方便快速查找 const lastYearIdMap = lastYearData.reduce((map, item) => { map[item.id] = item.purchase_value; return map; }, {}); // 合并数据并计算对比值 const mergedData = currentData.map(item => ({ id: item.id, currentValue: item.purchase_value, lastYearValue: lastYearIdMap[item.id] || 0, // 无去年数据时设为0 difference: item.purchase_value - (lastYearIdMap[item.id] || 0), differencePercent: lastYearIdMap[item.id] ? ((item.purchase_value - lastYearIdMap[item.id]) / lastYearIdMap[item.id] * 100).toFixed(2) : 'N/A' })); setComparisonData(mergedData); }, [currentData, lastYearData]);
3. 渲染对比表格
把处理好的对比数据渲染成HTML表格:
return ( <table border="1" cellPadding="8" style={{borderCollapse: 'collapse'}}> <thead> <tr> <th>采购ID</th> <th>当前采购值</th> <th>去年同期采购值</th> <th>差值</th> <th>差值百分比</th> </tr> </thead> <tbody> {comparisonData.map(item => ( <tr key={item.id}> <td>{item.id}</td> <td>{item.currentValue}</td> <td>{item.lastYearValue}</td> <td>{item.difference >= 0 ? `+${item.difference}` : item.difference}</td> <td>{item.differencePercent !== 'N/A' ? `${item.differencePercent}%` : item.differencePercent}</td> </tr> ))} </tbody> </table> ); }; export default PurchaseComparison;
核心要点
- 用
Promise.all并行请求,既解决了purchase_date参数无法传递的问题,又比串行请求更快。 - 用对象映射匹配ID,比嵌套循环查找效率高,适合数据量较大的场景。
- 处理了去年无对应ID数据的边界情况,避免出现计算错误或显示异常。
内容的提问来源于stack exchange,提问作者Anuprita Kasbekar Deshmukh
相关产品推荐
相关产品推荐

