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

Next.js 14组件间数据传递失败及子传父实现咨询

问题排查与解决方案

一、当前代码的错误点

1. About页面获取searchParams的方式错误

在Next.js App Router中,页面组件的props是一个包含searchParams的对象,你直接把参数当作searchParams接收,导致无法获取到实际数据。

2. Link组件的as属性导致Query丢失

App Router已废弃as属性,使用该属性会覆盖href中的query参数,跳转后About页面自然拿不到数据。

3. Query参数的长度限制(潜在问题)

将整个apiResult.data通过JSON.stringify放入query中,一旦数据量较大,会超出URL的长度限制,导致数据截断或丢失。

二、修正后的代码

1. 修正ProductData.tsx(移除as属性)

import Link from "next/link";
import { ApiData } from "./apiCall";

export const dynamic = "force-dynamic";

export default async function ProductData() {
  const apiResult = await ApiData();

  return(
      <div>
        {
            apiResult &&  apiResult.data?.products.map((item:any, id:number) => {
                  return(
                      <div key={id}>
                        <h4>Name: {item?.title}  Price: {item?.price} </h4>
                      </div>
                  )
              })
          }

        <Link
          href={{ 
            pathname: '/about', 
            query: { data: JSON.stringify(apiResult.data) } 
          }}
        >
          About Us
        </Link>
      </div>
  )
}

2. 修正About.tsx(正确获取searchParams)

export const metadata = {
  title: 'About page',
}

// 正确解构props中的searchParams
export default function About({ searchParams }: { searchParams: { data?: string } }) {
  console.log(searchParams);
  // 解析JSON字符串
  const productsData = searchParams.data ? JSON.parse(searchParams.data) : null;

  return(
    <div>
      <h1>About</h1>
      {productsData?.products.map((item:any, id:number) => (
        <div key={id}>{item?.brand}</div>
      ))}
    </div>
  )
}

三、更优的替代方案(避免Query传大数据)

URL的Query长度有限,不适合传递大量数据。如果两个页面都是服务器组件,直接在About页面调用ApiData获取数据更可靠:

// about.tsx
import { ApiData } from "@/app/products/apiCall";

export const metadata = {
  title: 'About page',
}

export default async function About() {
  const apiResult = await ApiData();
  const productsData = apiResult.data;

  return(
    <div>
      <h1>About</h1>
      {productsData?.products.map((item:any, id:number) => (
        <div key={id}>{item?.brand}</div>
      ))}
    </div>
  )
}

四、Next.js中子组件向父组件传递数据的方法

1. 客户端组件:回调函数传递

父组件定义回调函数并传给子组件,子组件触发时调用该函数传递数据:

// 父组件(客户端组件)
'use client';
import { useState } from 'react';
import ChildComponent from './ChildComponent';

export default function ParentComponent() {
  const [childData, setChildData] = useState<string>('');

  const handleDataFromChild = (data: string) => {
    setChildData(data);
  };

  return (
    <div>
      <ChildComponent onDataChange={handleDataFromChild} />
      <p>从子组件拿到的数据:{childData}</p>
    </div>
  );
}

// 子组件(客户端组件)
'use client';
interface ChildProps {
  onDataChange: (data: string) => void;
}

export default function ChildComponent({ onDataChange }: ChildProps) {
  const sendDataToParent = () => {
    onDataChange('来自子组件的数据');
  };

  return <button onClick={sendDataToParent}>传递数据给父组件</button>;
}

2. 服务器组件:共享数据源

服务器组件无交互能力,通常通过共享API调用、数据库查询等方式获取相同数据,无需手动传递。若需结合客户端交互,可使用客户端组件作为中间层,配合状态管理工具(如React Context、Zustand)。

3. 状态管理工具(复杂场景)

对于跨多层组件的数据传递,使用React Context、Zustand等状态管理库,将数据存入全局状态,父、子组件均可访问和修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:02:08