如何正确地在Next页面组件之间传递Props?

起因

最近在写 Next (v14 App Router)时,发现运行 next build 出现了以下错误:

python 复制代码
Linting and checking validity of types ...Failed compile.
"src/app/home/updatelog/bugfix/page.tsx" has an invalid "default" export: Type "{ type: number; }" is not valid.

查看报错是在 Next 进行类型检查时出现的,根据给出的文件路径查看相关文件:

tsx 复制代码
// updatelog/bugfix/page.tsx

export default function BugFixPage({ type }: { type: number }) {
  return <div>...</div>;
}

发现组件定义并没有错,而且传入的参数的类型也没写错。

但报错却出现了 export: Type "{ type: number; }" is not valid. ,试着取消传递参数,再重新 build 时,发现就没报错了。

在其父文件中,是这样定义的:

tsx 复制代码
// updatelog/page.tsx

export default function UpdateLogPage() {
  const [updatePage, setUpdatePage] = useState<string>("/home/updatelog/newfeature")

  const renderContent = () => {
    switch (updatePage) {
      // 这样的做法是错误的❌
      case "/home/updateLog/newfeature":
        return <NewFeature type={0} />;
      case "/home/updateLog/bugfix":
        return <BugFixPage type={1} />;
      default:
        break;
    }
  }

  ...
}

溯源

由于 Next 的路由是基于文件系统的,也就是说每个页面都是一个单独的组件文件,当然这里说的"每个页面"指的是在 pages 目录下或者 app 目录下的页面。正是由于这样的特点,Next 就不能像传统的 SPA 应用一样在组件之间传递 Props 了。但这并不是说 Next 的页面组件不能接受参数,它可以接受参数,但并不能像 SPA 应用一样可以接收从另一个组件传递过来的参数。

要在 Next 中的页面之间传递属性,可以通过 getStaticProps 、 getServerSideProps、fetch 等数据获取方法

getStaticProps

仅限 Pages Router 模式下才能使用

如果需要在构建时使用 Props ,则可以使用 getStaticProps 方法,它是在构建时运行的服务端函数,并返回一个对象,该对象作为 Props 传递给组件。

tsx 复制代码
import type { GetStaticProps } from "next";

export const getStaticProps: GetStaticProps = async (context) => {
  const res = await fetchAPI("...");

  return {
    props: {
      result: res.data,
    },
  };
};

export default function ResultPage({ result }) {
  return (
    <div>
      {result.map((item) => {
        <div key={item.id}>{item}</div>;
      })}
    </div>
  );
}

getServerSideProps

仅限 Pages Router 模式下才能使用

如果需要在请求时使用 Props ,可以使用 getServerSideProps 方法,它也是一个服务端函数,但会针对每个请求运行。

tsx 复制代码
import type { GetServerSideProps } from "next";

export const getServerSideProps: GetServerSideProps = async () => {
  const res = await fetchAPI("...");

  return {
    props: {
      result: res.data,
    },
  };
};

export default function ResultPage({ result }) {
  return (
    <div>
      {result.map((item) => {
        <div key={item.id}>{item}</div>;
      })}
    </div>
  );
}

fetch

在 App Router 模式下,可以直接 fetch 来获取数据

Next 扩展了原生的 fetch Web API ,额外添加了 配置缓存 和 重新验证行为。

可以在 服务器组件(Server Component)、路由处理程序(页面目录的API路由)、服务器操作(Server Action,在服务器上执行的异步函数)

tsx 复制代码
async function getData() {
  const res = await fetch("...", {
    // 配置缓存
    cache: 'force-cache',
    // 重新验证行为
    next: {
      revalidate: 3600
    },
  })

  return res.json()
}

export default async function FetchPage() {
  const data = await getData()

  return (
    <div>
      {data.map(i => {
        <div key={i}>{i}</div>
      })}
    </div>
  )
}

希望给遇到同样错误的同学一个思路。

相关推荐
拆房老料41 分钟前
ONLYOFFICE也能像Microsoft Word和WPS一样分别设置中西文字体
前端·html·word·开源软件·wps
Solis程序员1 小时前
Stripe 幂等表:把「不确定的重试」变成「查表返回」
前端·安全·bootstrap·php·agent
李纲明1 小时前
WordPress 站点变慢:按 TTFB → 缓存 → 查询 → 前端 分层排查(含配置注意)
前端·缓存·性能优化·wordpress·后端开发
程序人生8881 小时前
PDF 转 Word 版式错乱、表格丢失?DocConverter Web 格式互转引擎的保真实践
前端·人工智能·opencv·机器学习·pdf·word
粥里有勺糖2 小时前
安利一下最近用的桌面“Agent” | T3 Code
前端·github·ai编程
xy34532 小时前
Axure 9.0 动态面板基本操作
前端·ui·html·axure·原型·产品设计
不停喝水3 小时前
【前端转全栈java速通课】 项目实战④7-11节 操作数据库-登录-注册-修改密码-注销-mubatis-plus简化crud-
java·前端·数据库
一水鉴天3 小时前
统一对象拓扑(UOT)设计全链定稿:从三件事分离到三继承 之1 20261010(豆包“查看聊天内容”继续)
前端·css
栖凤4 小时前
Java 的 try-catch 在 Agent 里失效了,我用了 5 个模式才兜住
java·前端·python
粥里有勺糖4 小时前
视野修炼第136期 | 前端小恐龙"Deno"被收购
前端·github·ai编程