React 创建与嵌套组件完全指南
写给刚跑通
npm run dev的你
5 分钟掌握「写-拆-套」三板斧,顺带把 Props 和 Children 讲透
1. 为什么一定要“拆”组件?
| 不拆 | 拆 |
|---|---|
| 1000 行大文件 | 10 行小组件 |
| 改一个按钮怕崩全局 | 独立测试/复用 |
| 新人不敢动 | 并行开发 |
一句话:组件 = 函数,函数越小越好维护。
2. 创建组件的 3 种姿势
① 函数组件(推荐 2025+)
// src/components/Greeting.tsx
type Props = { name: string };
export default function Greeting({ name }: Props) {
return <h1>Hello, {name}!</h1>;
}
② 箭头函数(一行党)
export const Emoji = ({ icon }: { icon: string }) => <span>{icon}</span>;
③ Class 组件(遗产代码)
import { Component } from 'react';
export class OldTimer extends Component<{ time: Date }> {
render() {
return <p>Now: {this.props.time.toLocaleTimeString()}</p>;
}
}
3. 嵌套组件:像搭乐高一样
场景:评论区卡片
目录
src/components/CommentCard.tsx
src/components/Avatar.tsx
src/components/LikeButton.tsx
Avatar.tsx
type Props = { src: string; size?: number };
export default function Avatar({ src, size = 32 }: Props) {
return (
<img
src={src}
width={size}
height={size}
style={{ borderRadius: '50%' }}
alt="avatar"
/>
);
}
LikeButton.tsx
import { useState } from 'react';
export default function LikeButton({ initial = 0 }: { initial?: number }) {
const [likes, setLikes] = useState(initial);
return (
<button onClick={() => setLikes(likes + 1)}>
👍 {likes}
</button>
);
}
CommentCard.tsx(嵌套点)
import Avatar from './Avatar';
import LikeButton from './LikeButton';
type Props = {
author: string;
avatar: string;
content: string;
};
export default function CommentCard({ author, avatar, content }: Props) {
return (
<div style={{ display: 'flex', gap: 12, borderBottom: '1px solid #eee', padding: 12 }}>
<Avatar src={avatar} />
<div>
<strong>{author}</strong>
<p>{content}</p>
<LikeButton />
</div>
</div>
);
}
使用:
// App.tsx
import CommentCard from './components/CommentCard';
function App() {
return (
<CommentCard
author="小高"
avatar="https://i.pravatar.cc/100"
content="React 拆组件真香!"
/>
);
}
4. Props & Children:让嵌套更灵活
透传任意子节点
// Card.tsx
type Props = { title: string; children: React.ReactNode };
export default function Card({ title, children }: Props) {
return (
<section style={{ border: '1px solid #ccc', padding: 16 }}>
<h3>{title}</h3>
{children}
</section>
);
}
使用:
<Card title="动态子节点">
<p>随便放什么标签都可以</p>
<LikeButton />
</Card>
5. 常见坑 & 小技巧
| 坑 | 解决 |
|---|---|
| 组件名必须大写开头 | function like() ❌ function Like() ✅ |
忘记 key 警告 | 列表渲染时加 key={唯一值} |
| 直接修改 props | props 只读,想改 → 内部用 useState |
7. 小结
- 创建:函数组件 + TypeScript Props
- 嵌套:import → 使用 → 组合
- 复用:Props 传参、Children 插槽
现在就把你的首页大文件按功能切成 5-10 个小组件,热更新后你会发现:
“原来 React 只是一个不断拆函数的循环。”