我现在想不出一个有效的解决方案来解决我的问题.实际上,我在前一页上有一个搜索栏,允许用户输入城市位置(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;

推荐答案

您已经有了一个用于根据位置获取数据的函数fetchConcerts和效果.不要重复这个逻辑(103原则).handleLocationSubmit回调应该向具有新的location路径参数的同一路由发出命令性导航动作.

示例:

export default function Concerts() {
  const navigate = useNavigate();

  ...

  const { location } = useParams();

  useEffect(() => {
    const fetchConcerts = async () => {
      const concertResponse = await fetch(`${process.env.REACT_APP_BUDDY_API}/api/selectconcertsforcity/${location}/&p=${page}`);
      ...
    };

    fetchConcerts();
  }, [location, page]);

  const handleLocationSubmit = (e) => {
    e.preventDefault();

    const location = city.replaceAll(" ", "%20");

    // reset back to page 1
    setPage(1);

    // navigate to update `location` path param and trigger rerender
    navigate(`./${location}`);
  };

  ...

Javascript相关问答推荐

模块与独立组件

jQuery提交按钮重新加载页面,即使在WordPress中使用preventDefault()

我不知道为什么setwritten包装promise 不能像我预期的那样工作

如何在Javascript中的控制台上以一行形式打印循环的结果

为什么promise对js中的错误有一个奇怪的优先级?

Google maps API通过API返回ZERO_RESULTS,以获得方向请求,但适用于Google maps

CheckBox作为Vue3中的一个组件

如何将react—flanet map添加到remixjs应用程序

S文本内容和值不必要的不同

try 使用javascript隐藏下拉 Select

连接到游戏的玩家不会在浏览器在线游戏中呈现

为什么我的按钮没有从&q;1更改为&q;X&q;?

自定义图表工具提示以仅显示Y值

如果一个字符串前面有点、空格或无字符串,后面有空格、连字符或无字符串,则匹配正则表达式

如何找到带有特定文本和测试ID的div?

使用Reaction窗体挂钩注册日历组件

React数组查找不读取变量

如何使用fltter_js将对象作为参数传递给javascrip?

在HTML中使用meta标记来指定定制元数据以用于使用JavaScript进行检索是不是一个坏主意?

Google OAuth 2.0库和跨域开放程序的问题-策略错误