如何在ReactJS中实现日期范围筛选及动态数据渲染
功能实现方案
前端代码(React)
import { useState, useEffect } from 'react'; import { Line } from 'react-chartjs-2'; const BASE_URL = "http://localhost:8080/sites"; const SelectSingle = () => { const [sites, setSites] = useState([]); const [selectedCellName, setSelectedCellName] = useState(''); const [startDate, setStartDate] = useState(''); const [endDate, setEndDate] = useState(''); const [filteredData, setFilteredData] = useState([]); // 日期格式转换:输入yyyy-mm-dd转成数据库存储的dd/mm/yyyy格式 const formatDateToDb = (dateStr) => { const [year, month, day] = dateStr.split("-"); return `${day}/${month}/${year}`; }; // 将dd/mm/yyyy格式的字符串转成Date对象用于范围比较 const parseDbDate = (dbDateStr) => { const [day, month, year] = dbDateStr.split("/"); return new Date(year, Number(month)-1, day); }; // 统一筛选逻辑 const filterData = () => { if (!selectedCellName || !startDate || !endDate) return; const startObj = parseDbDate(formatDateToDb(startDate)); const endObj = parseDbDate(formatDateToDb(endDate)); const result = sites.filter(site => { // 匹配选中的站点 if (site.Cell_Name !== selectedCellName) return false; // 匹配日期范围 const currentDate = parseDbDate(site.Traffice_Date); return currentDate >= startObj && currentDate <= endObj; }); setFilteredData(result); }; // 组件挂载时拉取全量站点数据(数据量小可用此方案,数据量大建议走后端筛选) useEffect(() => { fetch(BASE_URL) .then(res => res.json()) .then(data => setSites(data)); }, []); // 筛选条件变更时重新过滤数据 useEffect(() => { filterData(); }, [selectedCellName, startDate, endDate]); // 图表数据组装 const chartData = { labels: filteredData.map(item => item.Traffice_Date), datasets: [ { label: "E_RAB_Setup_Success_Rate", backgroundColor: "rgba(75,192,192,1)", borderColor: "rgba(0,0,0,1)", borderWidth: 2, data: filteredData.map(item => item.E_RAB_Setup_Success_Rate), }, ], }; return ( <div> <div className="data-class"> <select onChange={(e) => setSelectedCellName(e.target.value)} value={selectedCellName}> <option value="">请选择站点</option> {/* 站点去重,避免下拉选项重复 */} {[...new Map(sites.map(site => [site.Cell_Name, site])).values()].map((site, index) => ( <option value={site.Cell_Name} key={index}> {site.Cell_Name} </option> ))} </select> <h2>From</h2> <input type="date" value={startDate} onChange={(e) => setStartDate(e.target.value)} name="startDate" /> <h2>To</h2> <input type="date" value={endDate} onChange={(e) => setEndDate(e.target.value)} name="endDate" /> </div> <div> <table> <thead> <tr> <th>E_NodeB</th> <th>Cell_Name</th> <th>Date</th> <th>E_RAB_Setup_Success_Rate</th> <th>Data_Traffic_DL</th> <th>Data_Traffic_UL</th> <th>UL_Throughput</th> </tr> </thead> <tbody> {filteredData.map((site, index) => ( <tr key={index}> <td>{site.eNodeB_Name}</td> <td>{site.Cell_Name}</td> <td>{site.Traffice_Date}</td> <td>{site.E_RAB_Setup_Success_Rate}</td> <td>{site.Data_Traffic_DL}</td> <td>{site.Data_Traffic_UL}</td> <td>{site.G_UL_Throughput_IK}</td> </tr> ))} </tbody> </table> <Line data={chartData} options={{ title: { display: true, text: "Plot of E_RAB_Setup_Success_Rate", fontSize: 20, }, legend: { display: true, position: "right", }, }} /> </div> </div> ); }; export default SelectSingle;
后端代码(Express+MySQL)
修复原有语法错误,新增支持参数化筛选的逻辑(数据量较大时推荐使用):
const express = require("express"); const cors = require("cors"); const mysql = require("mysql2"); const app = express(); const connection = mysql.createConnection({ host: "localhost", user: "a", password: "123", database: "aa", }); connection.connect((err) => { if (err) throw err; console.log("Connected to MySQL Server!"); }); app.use(cors()); app.get("/", function (req, res) { connection.query("SELECT * FROM africell_data LIMIT 10", (err, rows) => { if (err) throw err; res.json(rows); }); }); app.get("/sites", function (req, res) { const { cellName, startDate, endDate } = req.query; let sql = `SELECT eNodeB_Name,Cell_Name,Traffice_Date,E_RAB_Setup_Success_Rate,Data_Traffic_DL,Data_Traffic_UL,G_UL_Throughput_IK FROM africell_data`; let params = []; // 传入筛选参数则走范围查询逻辑 if (cellName && startDate && endDate) { sql += ` WHERE Cell_Name = ? AND STR_TO_DATE(Traffice_Date, '%d/%m/%Y') BETWEEN STR_TO_DATE(?, '%d/%m/%Y') AND STR_TO_DATE(?, '%d/%m/%Y')`; params = [cellName, startDate, endDate]; } connection.query(sql, params, (err, rows) => { if (err) throw err; res.json(rows); }); }); app.listen(8080, () => { console.log(`App running on port 8080`); });
修复说明
- 移除硬编码的站点名称,复用下拉框选中的站点值
- 新增日期范围比较逻辑,支持选中起止日期后展示区间内所有符合条件的数据
- 修复表格表头和内容顺序不匹配的问题
- 下拉选项新增去重逻辑,避免相同站点重复展示
- 修复useEffect无依赖项导致的重复请求问题
- 后端新增参数化查询逻辑,避免SQL注入,优化大数据量下的筛选性能
- 移除原有代码中的语法错误(如多余的
enter code here片段)
内容的提问来源于stack exchange,提问作者Alpha Alimamy Kamara
相关产品推荐
相关产品推荐

