如何获取URL中的QueryString参数并在useEffect中使用?
问题解决:正确传递URL查询参数到useEffect进行API调用
问题根源
你当前的代码把useSearchParams放在了内部子组件Search中,导致id的赋值时机晚于useEffect的首次执行。组件初始化时useEffect先触发,此时id还是undefined;等Search组件渲染后id才被赋值,但useEffect的依赖adUlid已经是初始值,不会重新触发,所以API调用拿不到正确的id。
修复方案
直接在GetAd组件顶层调用useSearchParams,确保组件初始化时就能获取到URL中的id参数,同时将id作为useEffect的依赖项,当id变化时自动重新执行API调用。
修改后的完整代码
"use client"; // This is a client component import { useState, useEffect, Suspense } from 'react'; import { Client } from '@/generated/generated_admanager_client'; import withAuth from '@/components/with-auth'; import { GetAdDto } from '@/generated/generated_admanager_client'; import { useRouter, useSearchParams } from 'next/navigation'; function AdElement(ad: GetAdDto) { return ( <li key={ad.ulid}> <h2>{ad.title}</h2> <p>{ad.description}</p> <p>{ad.creationDate?.toString()}</p> </li> ); } function GetAd() { const router = useRouter(); const [ad, setAd] = useState<GetAdDto>(); const [error, setError] = useState<string | null>(null); // 直接在组件顶层获取searchParams const searchParams = useSearchParams(); const adUlid = searchParams.get('id'); // 直接拿到id参数 useEffect(() => { const client = new Client(); console.log('--------------- useffect'); console.log(adUlid); console.log('/--------------- useffect'); if (adUlid) { client.adsGET2(adUlid) .then(response => { console.log('--------------- response'); console.log(response); setAd(response.ads[0]); console.log('/--------------- response'); }) .catch(err => { switch (err.status) { case 400: setError("Bad Request"); break; case 401: setError("Unauthorized"); break; case 403: setError("Forbidden"); break; case 404: setError("Not Found"); break; case 500: setError("Internal Server Error"); break; default: setError("Failed to fetch ads"); } console.error("Error fetching ad:", err); }); } else { // router.push('/ads/list.html'); return; } }, [adUlid, router]); // 依赖adUlid,变化时重新执行 return ( <Suspense> <div> {error && <p>{error}</p>} <ul> {ad && AdElement(ad)} </ul> </div> {/* 如果需要搜索输入框,直接在这里渲染即可,不需要单独组件 */} <input placeholder="Search..." /> </Suspense> ); } export default withAuth(GetAd);
关键改动点
- 移除了内部的
Search组件,直接在GetAd组件顶层调用useSearchParams,符合React Hooks的调用规则(必须在组件顶层或自定义Hook中调用) - 直接获取
adUlid,确保组件初始化时就能拿到URL参数 - 将
adUlid加入useEffect的依赖数组,当URL中的id参数变化时,useEffect会自动重新执行API调用 - 如果需要搜索输入框,直接在返回的JSX中渲染即可,无需封装成单独组件(如果有复杂逻辑可以抽成组件,但不要在组件内部调用
useSearchParams来影响父组件的状态)
内容的提问来源于stack exchange,提问作者Kinjo
相关产品推荐
相关产品推荐

