[react 18+] 定义页面组件时的三种申明区分
- function MyComponent({ name }: { name: string })
- const MyComponent = ({ name }: { name: string })
- const MyComponent: FC<{ name: string }> = ({ name })
这三种写法在功能上是等价的,都能正确渲染组件,但在 TypeScript 类型检查、代码风格 和 可扩展性 上有一些区别:
1. export default function 直接声明(内联 Props 类型)
function MyComponent({ name }: { name: string }) {return <div>{name}</div>;
}export default MyComponent
✅ 特点:
- 最简洁:适合简单组件,props 类型直接内联
- 无额外导入:不需要 import { FC }
- 适合:不需要复用 props 类型或扩展的简单组件
2. const 箭头函数 + 解构 Props(分离 Props 类型)
interface Props {name: string;
}const MyComponent = ({ name }: Props) => {return <div>{name}</div>;
};export default MyComponent;
✅ 特点:
- 类型可复用:Props 接口可被其他组件复用
- 更易扩展:添加新 props 时只需修改 interface
- 显式命名:Props 让类型定义更清晰
- 适合:中等复杂度的组件
3. FC 泛型写法(React 传统风格)
import { FC } from 'react';const MyComponent: FC<{ name: string }> = ({ name }) => {return <div>{name}</div>;
};export default MyComponent;
✅ 特点:
- 显式类型标注:明确声明这是一个函数组件
- 历史原因:React 早期推荐写法(现在已非必须)
- 自动包含 children:在 React 17 及之前,FC 会默认添加 children?: ReactNode(React 18 已移除)
- 适合:需要兼容旧代码或团队规范要求时
🔍 关键区别总结
🚀 现代 React + TypeScript 最佳实践建议
1. 简单组件:直接用 export default function + 内联 props(快速原型开发)
export default function Button({ text }: { text: string }) {return <button>{text}</button>;
}
2. 复杂组件:用 const + 独立 interface(清晰且可扩展)
interface UserCardProps {name: string;age: number;onFollow?: () => void;
}const UserCard = ({ name, age, onFollow }: UserCardProps) => {return <div>{name}, {age}</div>;
};
3. 需要 children:手动声明(React 18+ 统一方式)
interface LayoutProps {children: React.ReactNode;
}const Layout = ({ children }: LayoutProps) => {return <div className="container">{children}</div>;
};
4. 避免 FC:除非团队规范要求或维护旧代码
⚠️ 特别注意
- React 18 后:FC 不再自动包含 children 类型,它的优势已不明显
- 性能:三种写法编译后完全一致,无运行时差异
- 一致性:项目中最好统一一种风格