React搜索查询中清除旧Param值并使用新值的高效方案问询
React项目问题解决方案
问题1:旧location参数干扰新查询
在Concerts页面搜索新城市时,旧的URL参数location会触发useEffect重新执行,覆盖手动提交的查询结果。核心原因是handleLocationSubmit直接获取数据但未同步更新URL,导致组件同时受本地提交和URL参数两个来源的冲突影响。
解决办法:
- 在
handleLocationSubmit中,不再直接调用fetch,而是通过navigate跳转到包含新城市的路由,同时重置页码为1。 - 让useEffect统一处理路由参数变化后的逻辑,所有数据获取都由路由参数驱动,避免冲突。
问题2:代码重复问题
useEffect里的fetchConcerts和handleLocationSubmit逻辑几乎完全重复,将公共逻辑提取为独立函数即可解决。
具体实现代码修改
1. 提取公共复用函数(Concerts.js)
把日期转换、数据请求与解析逻辑抽离成通用函数:
// 统一处理日期格式转换 const formatEventDate = (dateStr) => { const dateParts = dateStr.split("-"); return new Date(+dateParts[2], dateParts[1] - 1, +dateParts[0]); }; // 通用演出数据获取函数 const fetchConcerts = async (targetCity, targetPage) => { try { const encodedCity = encodeURIComponent(targetCity); const concertResponse = await fetch( `${process.env.REACT_APP_BUDDY_API}/api/selectconcertsforcity/${encodedCity}/&p=${targetPage}` ); if (!concertResponse.ok) throw new Error('请求失败'); const concertData = await concertResponse.json(); if (!concertData.concerts?.setlist) { setInvalid(true); setConcerts([]); return; } // 批量转换日期格式 const formattedConcerts = concertData.concerts.setlist.map(concert => ({ ...concert, eventDate: formatEventDate(concert.eventDate) })); // 过滤仅保留未来的演出 const futureConcerts = formattedConcerts.filter( concert => concert.eventDate >= Date.now() ); setConcerts(futureConcerts.length > 0 ? futureConcerts : 0); setArtist(''); setInvalid(false); } catch (err) { console.error('获取演出数据失败:', err); setInvalid(true); setConcerts([]); } };
2. 简化useEffect逻辑(Concerts.js)
让useEffect仅监听路由参数和页码变化,调用公共函数:
useEffect(() => { if (location) { fetchConcerts(location, page); // 同步更新输入框值,避免输入框与路由参数不一致 setCity(decodeURIComponent(location)); } }, [location, page]);
3. 修改handleLocationSubmit逻辑(Concerts.js)
通过路由跳转替代直接fetch,统一数据获取入口:
const handleLocationSubmit = async (e) => { e.preventDefault(); if (!city.trim()) return; // 跳转时编码城市名,避免特殊字符问题 navigate(`/selectconcerts/${encodeURIComponent(city)}`); setPage(1); };
4. 优化HeroSection的跳转逻辑(HeroSection.js)
同样用编码处理城市名,避免空格等特殊字符导致路由异常:
const handleImGoingSubmit = async (e) => { e.preventDefault(); if (!city.trim()) return; navigate(`/selectconcerts/${encodeURIComponent(city)}`); };
最终效果
- 无论从HeroSection跳转还是在Concerts页面搜索新城市,都会同步更新URL参数,useEffect统一触发数据获取,彻底解决旧参数干扰问题。
- 所有数据请求、日期处理逻辑复用同一函数,消除代码重复,后期维护更便捷。
内容的提问来源于stack exchange,提问作者Victoria
相关产品推荐
相关产品推荐

