返回文章

Next.js 语法问题

一、Next.js Server Action 表单绑定方式 两种方式对比 1. ❌ 错误方式(原代码) fo

一、Next.js Server Action 表单绑定方式

两种方式对比

1. ❌ 错误方式(原代码)

<form className="flex-1 flex flex-col min-w-64">
  <Input name="email" />
  <SubmitButton formAction={signInAction}>Sign in</SubmitButton>
</form>

formAction 属性放在 button 上,只有在纯客户端表单中才有效。但在 Next.js 服务器组件渲染的页面中,这种方式可能无法正确绑定。


2. ✅ 正确方式(修改后)

<form className="flex-1 flex flex-col min-w-64" action={signInAction}>
  <Input name="email" />
  <SubmitButton>Sign in</SubmitButton>
</form>

action 属性放在 form 标签上,这是 HTML 标准表单提交方式,更可靠。


为什么这样修改?

特性 formAction (button 上) action (form 上)
HTML 标准 ✅ 支持 ✅ 支持
Next.js 服务器组件 ⚠️ 可能失效 ✅ 完全支持
多按钮表单 ✅ 不同按钮提交不同动作 ❌ 整个表单只能一个 action
简单单提交表单 ✅ 可用 ✅ 推荐

本项目的情况

这个登录/注册表单只有一个提交按钮,所以把 action 放在 form 标签上是最简单可靠的方式:

// signInAction 和 signUpAction 都是 Server Action
export const signInAction = async (formData: FormData) => {
  const email = formData.get("email") as string;
  const password = formData.get("password") as string;
  // ... 处理逻辑
};

当用户点击提交按钮时:

  1. 表单数据通过 POST 提交到 action 指定的 Server Action
  2. Server Action 在服务器端执行(访问数据库、调用 API 等)
  3. 执行 redirect() 跳转到目标页面

这就是 Next.js App Router 推荐的表单提交模式。

二、项目语法问题

👉.ts = 纯 TypeScript 文件 写逻辑 👉 .tsx = 可以写 JSX(React 代码)的 TypeScript 文件 写界面

👉 优先用 export const(命名导出) 👉 只有在“明确唯一入口”的场景才用 export default


三、核心区别(本质)

对比点 export default export const
数量 只能 1 个 可以多个
导入方式 自定义名字 必须同名
可读性 ❌ 不直观 ✅ 很清晰
重构友好 ❌ 差 ✅ 好
推荐程度 ⭐⭐ ⭐⭐⭐⭐

✅ 1. 可读性更强

// utils.ts
export const add = () => {};
export const sub = () => {};

导入时:

import { add, sub } from "./utils";

👉 一眼知道用了哪些函数 👍


❌ default 的问题

export default function add() {}
import abc from "./utils";

👉 abc 是啥??完全看不出来 😅


✅ 2. 更利于团队协作

多人开发时:

👉 命名导出强制统一名字 👉 不会出现:

import fn1 from "./utils";
import fn2 from "./utils";

这种混乱情况


✅ 3. 更好重构(非常关键)

IDE(比如 VSCode):

👉 对命名导出支持更好(自动重命名、跳转)

👉 只在这些场景用(记住这几个就够了)


✅ 1. React / Next.js 页面

export default function Page() {
  return <div>首页</div>;
}

👉 框架要求必须 default


✅ 2. 单一核心模块

比如:

export default class UserService {}

👉 这个文件就干一件事


✅ 3. UI组件(有争议)

export default function Button() {}

👉 有些团队允许这样写


1. 工具函数 → 一律 export const
2. hooks → export const
3. 常量 / 类型 → export const / export type
4. 页面 → export default(必须)
5. 单一类 / 服务 → 可用 default

❌ 不推荐写法

// utils.ts
export default function add() {}
import xxx from "./utils"; // ❌ 不清晰

✅ 推荐写法

// utils.ts
export const add = () => {};
import { add } from "./utils"; // ✅ 清晰

你可以这样总结:

在实际项目中我更倾向使用 export const,因为它具备更好的可读性、可维护性和重构友好性,特别是在多人协作时可以避免命名混乱。 只有在明确单一导出的场景,比如 Next.js 页面或模块入口时,我才会使用 export default。


👉 Tree Shaking(打包优化)

  • export const 👉 更容易被优化掉未使用代码 ✅
  • export default 👉 有时不容易优化 ❌

👉 开发优先用 export const,框架要求才用 export default