Skip to content

你的第一个组件

🌟 概述

  • 🔍 组件定义:UI构建块,可复用的界面元素
  • 🎯 核心地位:React应用的基础构建单元
  • 💡 本质特点:JavaScript函数 + JSX标签

🧱 组件:UI的构成要素

🔄 从HTML到组件的演变

  • 🌐 传统Web:使用原生HTML标签(如<h1><li>)构建页面
  • 🧩 React创新:自定义组件允许封装和复用UI结构
  • 🛠️ 组件优势:将相关的标签、CSS和JavaScript组合成一个可复用单元
jsx
// 传统HTML结构
<article>
  <h1>我的标题</h1>
  <ul>
    <li>项目一</li>
    <li>项目二</li>
  </ul>
</article>

// React组件形式
<Article>
  <Title>我的标题</Title>
  <ItemList>
    <Item>项目一</Item>
    <Item>项目二</Item>
  </ItemList>
</Article>

🌉 组件的组合与嵌套

  • 🧠 组合模式:大组件由小组件组成,形成组件树
  • 🎯 结构清晰:通过组件嵌套反映UI的层次结构
  • 🔍 可维护性:独立组件更易于管理和更新
jsx
// 组件的组合示例
<PageLayout>
  <NavigationHeader>
    <SearchBar />
    <Link />
  </NavigationHeader>
  <Sidebar />
  <MainContent>
    <ArticleList />
    <Pagination />
  </MainContent>
</PageLayout>

📝 定义组件的步骤

1️⃣ 导出组件

  • 📤 语法:使用export default前缀
  • 🔍 目的:使组件可以在其他文件中导入使用
  • 🌐 注意:这是JavaScript标准语法,非React特有功能
jsx
export default function Profile() {
  // 组件内容
}

2️⃣ 定义函数

  • 📋 语法:创建一个JavaScript函数
  • 🚨 命名规则:组件名必须以大写字母开头
  • 🧠 原因:React用大小写区分自定义组件和原生HTML标签
jsx
// ✅ 正确:以大写字母开头
function Profile() { }

// ❌ 错误:小写开头会被视为HTML标签
function profile() { }

3️⃣ 添加标签

  • 📝 返回内容:函数返回JSX(JavaScript XML)标签
  • 🌉 JSX特点:在JavaScript中嵌入类HTML标签的语法
  • ⚠️ 括号规则:若JSX标签与return不在同一行,必须用括号包裹
jsx
// 单行JSX不需要括号
return <img src="avatar.jpg" alt="个人头像" />;

// 多行JSX必须用括号包裹
return (
  <div>
    <img src="avatar.jpg" alt="个人头像" />
    <h2>用户名</h2>
  </div>
);

🚨 常见错误:没有括号包裹的多行JSX会导致return后的代码被忽略!

🖥️ 使用组件

📌 组件调用语法

  • 🔍 JSX语法:使用类似HTML标签的形式 - <ComponentName />
  • 🔠 大小写区分
    • 小写标签 (<div>) → HTML原生元素
    • 大写标签 (<Profile>) → React自定义组件
  • 🔄 渲染过程:组件最终会被转换为HTML呈现给浏览器
jsx
// Profile组件的定义
function Profile() {
  return <img src="avatar.jpg" alt="头像" />;
}

// 使用Profile组件
function Gallery() {
  return (
    <section>
      <h1>用户画廊</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

👁️ 浏览器看到的内容

浏览器最终看到的是组件渲染后的HTML结构,而非JSX语法:

html
<!-- 浏览器实际看到的HTML -->
<section>
  <h1>用户画廊</h1>
  <img src="avatar.jpg" alt="头像" />
  <img src="avatar.jpg" alt="头像" />
  <img src="avatar.jpg" alt="头像" />
</section>

🧩 组件的组织方式

  • 📂 文件组织:多个相关组件可放在同一文件中,也可拆分为单独文件
  • 🔀 组件关系:可用"父子关系"描述组件之间的嵌套关系
  • ⚠️ 禁忌:不要在组件内部定义其他组件
jsx
// ✅ 正确:在顶层定义组件
function Gallery() { /* ... */ }
function Profile() { /* ... */ }

// ❌ 错误:不要嵌套定义组件
function Gallery() {
  function Profile() { /* ... */ } // 会导致性能问题和bug
  // ...
}

🔍 深入理解组件

🌐 万物皆组件

  • 🎯 组件用途:不仅用于小型UI元素,也用于完整页面布局
  • 🔄 组合思想:大型UI由越来越小的组件嵌套组成
  • 🧩 灵活使用:可以根据需要使用尽可能多或少的组件

🚀 React应用结构

  • 🏗️ 根组件:应用的起点,通常在框架中自动创建
    • 在普通React应用中:通常在src/App.js
    • 在Next.js中:通常在pages/index.js
  • 🌲 组件树:从根组件开始,形成组件的层次结构

🧠 组件思维方式

  • 🔍 UI拆解:将界面拆分成独立、可复用的部分
  • 🎯 关注分离:每个组件负责特定的功能或展示
  • 🔄 组合代替继承:通过组合小组件构建复杂界面

💡 最佳实践

📏 命名与定义规范

  • 🔠 组件名:始终使用大写字母开头(PascalCase)
  • 📂 组件定义:保持在文件顶层,不在其他组件内部定义
  • 🎯 单一职责:每个组件专注于特定功能或UI部分

🧰 组件设计技巧

  • 🧩 适度拆分:既不过度拆分也不过度合并
  • 🔍 语义化命名:组件名应反映其功能或内容
  • 📦 适当复用:提取常用模式为独立组件

⚠️ 常见错误与解决方案

  • 🚨 组件名小写:React会将其视为HTML标签而非组件
  • 🔄 返回多个元素:需要用一个父元素包裹
  • 🧠 嵌套定义组件:导致性能问题和React Hooks错误

📝 总结

  • 🧩 组件本质:JavaScript函数 + JSX返回值
  • 📏 定义步骤
    1. 导出组件 (export default)
    2. 定义函数 (大写字母开头)
    3. 返回JSX (多行需用括号包裹)
  • 🔍 使用方式:作为JSX标签使用 <ComponentName />
  • 🚀 组件优势
    • 代码复用性高
    • UI结构清晰
    • 关注点分离
    • 易于维护和测试

参考:React官方文档-你的第一个组件