我现在想不出一个有效的解决方案来解决我的问题.实际上,我在前一页上有一个搜索栏,允许用户输入城市位置(heropage.js).然后导航到音乐会列表页面(seltconcert.js),该页面使用useParams()挂钩从url获取城市名称来描述来自该城市的所有音乐会.
我遇到的问题如下:如果用户愿意,我希望用户能够在seltconcerts.js页面上查找新的城市,并清除useParams(),这样它就不会中断.目前,因为我将useEffect挂钩与useParams一起使用,所以有时会因为新的城市搜索查询而中断旧的位置参数.我还觉得,通过在useEffect挂钩中使用fetchConcerts函数并使用handleLocationSubmit函数来处理单独的查询(取决于它是在上一页还是当前页上搜索的),我就像是在复制代码.我try 过使用Searchpars,但如果您有更有效的解决方案,请告诉我.
Seltconcert.js(演唱会列表页面)
export default function Concerts() {
let navigate = useNavigate()
const [concerts, setConcerts] = useState([]);
const [city, setCity] = useState('');
const [artist, setArtist] = useState('');
const [toggled, setToggled] = useState(false);
const [invalid, setInvalid] = useState(false);
const [page, setPage] = useState(1)
let {user} = useContext(AuthContext)
const yesterday = ( d => new Date(d.setDate(d.getDate()-1)) )(new Date());
let { location } = useParams();
useEffect( () => {
const fetchConcerts = async() => {
const concertResponse = await fetch(`${process.env.REACT_APP_BUDDY_API}/api/selectconcertsforcity/${location}/&p=${page}`)
if(concertResponse.ok) {
const concertData = await concertResponse.json();
if (concertData.concerts.setlist) {
for (let i in concertData.concerts.setlist){
const dateParts = concertData.concerts.setlist[i].eventDate.split("-");
const dateObject = new Date(+dateParts[2], dateParts[1] - 1, +dateParts[0]);
concertData.concerts.setlist[i].eventDate = dateObject
}
setConcerts(concertData.concerts.setlist);
let concList = [concertData.concerts.setlist.filter(concert => ((concert.eventDate)) >= (Date.now()))]
if (concList[0].length === 0){
setConcerts(0)
}
setArtist('');
setInvalid(false)
} else {
if (location !== undefined) {
setInvalid(true)
setConcerts([])
}
}
}
}
fetchConcerts();
}, [location, page]
);
const handleLocationSubmit = async (e) => {
e.preventDefault();
const city_new = city.split(' ')
let final_city = city_new[0]
for (let i = 1; i < city_new.length; i++) {
final_city += '%20'
final_city += city_new[i]
}
const concertResponse = await fetch(`${process.env.REACT_APP_BUDDY_API}/api/selectconcertsforcity/${final_city}/&p=1`)
if(concertResponse.ok) {
const concertData = await concertResponse.json();
if (concertData.concerts.setlist) {
for (let i in concertData.concerts.setlist){
const dateParts = concertData.concerts.setlist[i].eventDate.split("-");
const dateObject = new Date(+dateParts[2], dateParts[1] - 1, +dateParts[0]);
concertData.concerts.setlist[i].eventDate = dateObject
}
setConcerts(concertData.concerts.setlist);
let concList = [concertData.concerts.setlist.filter(concert => ((concert.eventDate)) >= (Date.now()))]
if (concList[0].length === 0){
setConcerts(0)
}
setArtist('');
setInvalid(false)
} else {
console.error('concertData:', concertResponse);
setInvalid(true)
setConcerts([])
}
}
}
.....
return (
<>
<div className='selectconcerts'>
<div>
<Toggle onChange={(e) => setToggled(e.target.checked)} />
<p> Search by {toggled ? "Artist": "City "}</p>
<div className='entry'>
{ toggled ?
<form onSubmit={handleArtistSubmit}>
<input className="form-control" type="text" value={artist} required onChange={(e) => {setArtist(e.target.value)}} onKeyPress={handleKeypress}/>
</form>
:
<form onSubmit={handleLocationSubmit}>
<input className="form-control" type="text" value={city} required onChange={(e) => {setCity(e.target.value)}} onKeyPress={handleKeypress}/>
</form>
}
<div>
<p></p>
</div>
Js(带有初始城市搜索查询选项的页面)
function HeroSection() {
let {user} = useContext(AuthContext)
const [city, setCity] = useState('');
let videoimage = require('./Images/video-3.mp4')
let navigate = useNavigate()
const handleImGoingSubmit = async (e) => {
e.preventDefault();
navigate(`/selectconcerts/${city}`)
}
const handleKeypress = e => {
//it triggers enter button by pressing the enter key
if (e.keyCode === 13) {
handleImGoingSubmit();
}
};
return (
<div className='hero-container'>
<video src={videoimage} autoPlay loop muted />
<h1 align="center">ADVENTURE AWAITS</h1>
{user ? (<p align="center">Hello {user.username}, what are you waiting for?</p>):(<p align="center">What are you waiting for?</p>)}
<div className='hero-btns'>
<form onSubmit={handleImGoingSubmit}>
<input className="form-control" type="text" placeholder="Search concerts by city..." value={city} required onChange={(e) => setCity(e.target.value)} onKeyPress={handleKeypress}/>
</form>
</div>
</div>
);
}
export default HeroSection;