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

router.query获取URL参数返回undefined,是否因路由未就绪导致?

Next.js中router.query获取artistId始终为undefined的解决方案

你的猜测没错,问题确实是路由未就绪时页面就尝试读取router.query导致的。Next.js在客户端初始化阶段,router.query不会立即填充完成,尤其是在页面首次加载或客户端导航的初期,这时候直接解构artistId就会得到undefined。

以下是具体的修复方案:

核心修复步骤

  • 等待路由就绪再执行数据请求:利用router.isReady状态判断路由是否完全加载完成,避免在未就绪时读取空的query参数。
  • 修正useEffect依赖项:移除不必要的依赖,避免无限循环。
  • 正确处理Firestore数据:文档快照需要调用.data()获取实际数据,同时判断文档是否存在。
  • 避免空值访问错误:初始状态下artist为空,需用可选链或条件渲染防止报错。

修改后的完整代码

import React, { useEffect, useState } from "react";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { getDoc, doc } from "firebase/firestore";
import { db } from "../api/auth/firebase/config";

import Head from "next/head";
import ArtistHeader from "../../components/ArtistHeader";
import UploadButton from "../../components/UploadButton";
import styles from "../../styles/artistPage.module.css";

export default function Artist() {
  const { data: session, status } = useSession();
  const [artist, setArtist] = useState(null);
  const router = useRouter();
  const { artistId } = router.query;

  useEffect(() => {
    if (status === "unauthenticated") {
      router.push("/auth/signin");
    }
  }, [status, router]);

  // 修正后的数据请求逻辑
  useEffect(() => {
    // 路由未就绪或无artistId时直接返回
    if (!router.isReady || !artistId) return;

    const fetchArtist = async () => {
      try {
        const artistRef = doc(db, "users", artistId);
        const docSnap = await getDoc(artistRef);
        
        if (docSnap.exists()) {
          setArtist(docSnap.data());
        } else {
          console.log("该艺术家不存在");
          // 可选:跳转到404页面
          // router.push("/404");
        }
      } catch (err) {
        console.error("获取艺术家数据失败:", err);
      }
    };
    fetchArtist();
  }, [router.isReady, artistId, router]);

  // 加载状态处理
  if (!artist) {
    return <div>加载中...</div>;
  }

  return (
    <section className={styles.wrapper}>
      <Head>
        <title>{artist.screenName || "艺术家页面"}</title>
      </Head>
      <div className={styles.artistPage}>
        <ArtistHeader artist={artist} />
        <div className={styles.songContainer}>
          <UploadButton />
        </div>
      </div>
    </section>
  );
}

额外注意事项

  • 若页面使用静态生成(SSG),可改用getStaticProps + getStaticPaths在服务端预获取数据,彻底规避客户端路由就绪问题。
  • 如果你使用Next.js 13+的App Router,路由参数需通过useParams()获取,逻辑会有所不同,但当前Pages Router的方案完全适用。

内容的提问来源于stack exchange,提问作者Yan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 03:35:22