You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:41:01