React 创建与嵌套组件完全指南

61 阅读2分钟

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={唯一值}
直接修改 propsprops 只读,想改 → 内部用 useState

7. 小结

  1. 创建:函数组件 + TypeScript Props
  2. 嵌套:import → 使用 → 组合
  3. 复用:Props 传参、Children 插槽

现在就把你的首页大文件按功能切成 5-10 个小组件,热更新后你会发现:
“原来 React 只是一个不断拆函数的循环。”