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

Next.js中如何传递卡片ID至路由并获取详情数据?

解决Next.js客户端组件无法async/await获取电影详情的问题

方案1:用useEffect + 状态管理实现基础数据获取

客户端组件不能直接将自身定义为async函数,可通过useEffect触发异步请求,配合useState管理数据、加载状态和错误信息:

'use client';

import { useState, useEffect } from 'react';
import axios from 'axios';
import { useParams } from 'next/navigation';

export default function MovieDetail() {
  const { id } = useParams();
  const [movie, setMovie] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchMovieDetail = async () => {
      try {
        setLoading(true);
        const response = await axios.get(`/api/movies/${id}`);
        setMovie(response.data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    if (id) fetchMovieDetail();
  }, [id]);

  if (loading) return <div>加载中...</div>;
  if (error) return <div>出错了:{error}</div>;
  if (!movie) return <div>未找到电影</div>;

  return (
    <div>
      <h1>{movie.title}</h1>
      <p>{movie.description}</p>
      {/* 其他详情内容 */}
    </div>
  );
}

方案2:使用SWR简化数据获取(Next.js推荐)

SWR是专为React/Next.js设计的数据获取库,内置缓存、重新验证等能力,比手动写useEffect更简洁:

'use client';

import useSWR from 'swr';
import axios from 'axios';
import { useParams } from 'next/navigation';

const fetcher = async (url) => {
  const response = await axios.get(url);
  return response.data;
};

export default function MovieDetail() {
  const { id } = useParams();
  const { data: movie, error, isLoading } = useSWR(id ? `/api/movies/${id}` : null, fetcher);

  if (isLoading) return <div>加载中...</div>;
  if (error) return <div>出错了:{error.message}</div>;
  if (!movie) return <div>未找到电影</div>;

  return (
    <div>
      <h1>{movie.title}</h1>
      <p>{movie.description}</p>
      {/* 其他详情内容 */}
    </div>
  );
}

方案3:混合服务端+客户端组件(性能更优)

如果详情页仅部分需要客户端交互,无需整页标记'use client'。可在服务端组件中完成数据获取,再将数据传给客户端组件:

服务端组件(app/movies/[id]/page.js)

import axios from 'axios';
import MovieDetailClient from './MovieDetailClient';

export default async function MovieDetailPage({ params }) {
  const { id } = params;
  const response = await axios.get(`https://your-api-domain/movies/${id}`);
  const movie = response.data;

  return <MovieDetailClient movie={movie} />;
}

客户端组件(app/movies/[id]/MovieDetailClient.js)

'use client';

// 这里编写需要客户端交互的逻辑,比如点赞、评论等
export default function MovieDetailClient({ movie }) {
  return (
    <div>
      <h1>{movie.title}</h1>
      <p>{movie.description}</p>
      {/* 客户端交互元素 */}
    </div>
  );
}

关键注意事项

  • 客户端组件不能将自身定义为async函数,React不支持这种写法,必须通过useEffect、数据获取库或服务端前置获取的方式处理异步数据。
  • 使用useParams获取ID时,需判断ID是否就绪,避免发起无效请求。
  • 优先选择服务端组件获取数据,再传给客户端组件,可减少客户端请求、提升页面性能与SEO表现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:45:00