当前位置: 首页 > news >正文

(三)React技术核心思想——组件化编程

一、从生活案例理解:什么是组件?

想象你要组装一台电脑:主机箱里有主板、CPU、显卡,显示器有屏幕、支架,这些"独立的、有特定功能的零件"就是组件。最后把这些零件拼在一起,就成了能正常工作的电脑。

React中的"组件"和这个逻辑完全一样:
组件是"具有独立功能的、可复用的代码块",是构成页面的最小功能单元。一个完整的页面,就是由多个组件像搭积木一样组合而成的。

举个网页的例子:
一个电商详情页可以拆成这些组件:

  • 导航栏组件(包含logo、搜索框、购物车按钮)
  • 商品图片组件(展示商品大图)
  • 商品信息组件(包含标题、价格、库存)
  • 加入购物车组件(按钮和数量选择器)
  • 评价列表组件(展示用户评论)
  • 页脚组件(包含联系方式、版权信息)

每个组件只负责自己的功能(比如"加入购物车组件"只处理点击加入和数量修改),最后组合起来就是完整的页面。

二、为什么React要强调组件化?—— 解决开发痛点

假设不用组件化开发一个电商网站,你可能会写出这样的代码:
一个HTML文件里堆了几千行代码,所有功能(导航、商品、评论)的HTML、CSS、JS混在一起。

  • 想改一下按钮样式?要在几千行代码里找对应的CSS;
  • 另一个页面也需要同样的导航栏?复制粘贴一大段代码,改一处地方要改所有复制的版本;
  • 新人接手项目?看代码看到头大,根本不知道哪部分对应哪部分功能。

而组件化能完美解决这些问题,核心优势有3点:

1. 复用性:写一次,到处能用

比如你写了一个"蓝色按钮"组件,只要在需要的地方"调用"它就行,不用重复写HTML和样式。
哪怕要改样式,只需要改这一个组件文件,所有用到它的地方都会自动更新。

2. 可维护性:责任清晰,改起来放心

每个组件只负责自己的功能,代码量少且独立。比如"评价列表组件"出了问题,只需要检查这个组件的代码,不用担心影响导航栏或购物车功能。

3. 协作高效:多人分工,互不干扰

大型项目中,多个开发者可以同时开发不同的组件(比如A开发导航栏,B开发商品信息),最后拼在一起就行,不会因为改了同一文件而冲突。

三、React组件的两种基本形式:函数组件 vs 类组件

React中有两种定义组件的方式,初学者首先要掌握函数组件(现在React官方更推荐),类组件作为了解即可。

1. 函数组件(重点!)

本质:一个返回React元素(JSX)的JavaScript函数
最简单的函数组件长这样:

// 定义一个函数组件(函数名首字母必须大写!)
function Welcome() {// 返回要显示的内容(JSX语法,后面详细讲)return <h1>欢迎学习React组件化!</h1>;
}
函数组件的核心规则:
  • 函数名必须首字母大写(React通过这个区分组件和普通HTML标签,比如<Welcome>是组件,<div>是普通标签);
  • 函数必须返回一个React元素(通常是JSX,也可以是null);
  • 函数内部可以包含逻辑(比如计算、条件判断),但最终要返回用于展示的内容。

2. 类组件(了解即可)

基于ES6的class语法定义的组件,需要继承React.Component,并实现render()方法返回内容。
基本形式:

// 导入React(旧版本必须,新版本可省略)
import React from 'react';// 定义类组件(类名首字母大写)
class Welcome extends React.Component {// 必须有render()方法,返回要显示的内容render() {return <h1>欢迎学习React组件化!</h1>;}
}
类组件和函数组件的简单对比:
特点函数组件类组件
语法像普通函数,简洁基于class,代码量稍多
状态管理用React Hooks(后续课程讲)用this.state和this.setState
适用场景大部分场景(推荐优先使用)复杂场景(逐步被函数组件替代)

初学者建议:先专注学函数组件,90%的基础场景用函数组件就能搞定。

四、JSX:组件的"模板语言"(必须掌握!)

上面的组件例子中,返回的<h1>欢迎学习React组件化!</h1>不是普通HTML,而是JSX(JavaScript XML的缩写)。
它是React提供的一种语法糖,允许你在JavaScript中直接写类似HTML的代码,最终会被编译成浏览器能理解的普通JavaScript。

为什么需要JSX?

如果不用JSX,想创建一个包含标题的React元素,需要写这样的代码:

// 不用JSX的写法(繁琐)
return React.createElement('h1', null, '欢迎学习React组件化!');

而用JSX,写法和HTML几乎一样,大大简化了代码。

JSX和HTML的异同(重点!)

相同点:
  • 基本标签写法一致(比如<div><p><h1>);
  • 标签嵌套规则一致(必须有闭合,比如<img /><input />)。
不同点(容易踩坑!):
  1. class属性要写成className
    因为class是JavaScript的关键字(用于定义类),所以JSX中用className代替:

    // 错误写法(会报错)
    <div class="box">内容</div>// 正确写法
    <div className="box">内容</div>
    
  2. 事件名要驼峰式命名
    比如HTML中的onclick,在JSX中要写成onClickonchange写成onChange

    // 错误写法
    <button onclick="handleClick()">点击</button>// 正确写法
    <button onClick={handleClick}>点击</button>
    
  3. 样式要用对象形式
    内联样式不能直接写字符串,要写成JavaScript对象(属性名驼峰式):

    // 错误写法
    <div style="color: red; font-size: 16px;">内容</div>// 正确写法
    <div style={{ color: 'red', fontSize: '16px' }}>内容</div>
    // 外层{}表示"这里是JavaScript",内层{}是样式对象
    
  4. 必须有一个根节点
    JSX返回的内容必须被一个根节点包裹(如果不想多一个div,可以用<></>空标签,称为Fragment):

    // 错误写法(多个根节点)
    return (<h1>标题</h1><p>段落</p>
    );// 正确写法(用div包裹)
    return (<div><h1>标题</h1><p>段落</p></div>
    );// 更简洁的写法(用空标签Fragment)
    return (<><h1>标题</h1><p>段落</p></>
    );
    
  5. 可以直接嵌入JavaScript变量
    {}包裹变量或表达式,就能在JSX中显示动态内容:

    function Welcome() {const name = "张三"; // 定义变量return (<h1>欢迎{name}学习React!</h1> // 用{}嵌入变量);
    }
    // 页面会显示:欢迎张三学习React!
    

五、组件的使用:导入、导出与组合

定义好的组件,需要"导出"才能被其他组件使用,使用时需要"导入",最后像HTML标签一样写在JSX中。

步骤1:创建并导出组件

通常一个组件放在一个单独的文件中(方便管理),文件名和组件名保持一致(首字母大写)。

比如创建一个Header.js文件(放在src目录下):

// src/Header.js
// 定义Header组件
function Header() {return (<header className="header"><h1>我的React博客</h1><nav><a href="/">首页</a><a href="/about">关于</a></nav></header>);
}// 导出组件(默认导出)
export default Header;
导出方式说明:
  • export default 组件名:默认导出,一个文件只能有一个默认导出;
  • 导入时可以自定义名称(但通常和组件名一致)。

步骤2:导入并使用组件

在需要使用组件的文件中(比如App.js),先导入组件,再像用HTML标签一样使用(注意首字母大写)。

修改src/App.js

// src/App.js
// 导入Header组件(从Header.js文件)
import Header from './Header';// 定义App组件(根组件)
function App() {return (<div>{/* 使用Header组件,就像用HTML标签一样 */}<Header />{/* 其他内容 */}<main><p>这是博客的正文内容</p></main></div>);
}export default App;

步骤3:运行效果

启动项目(npm start),浏览器会显示:

  • 顶部的Header组件内容("我的React博客"标题和导航链接);
  • 下面的正文内容。

这就是组件的组合:App组件包含了Header组件,形成了完整的页面结构。

再试一个:创建多个组件并组合

再创建一个Footer.js组件:

// src/Footer.js
function Footer() {return (<footer><p>© 2024 我的React博客 版权所有</p></footer>);
}export default Footer;

App.js中导入并使用:

// src/App.js
import Header from './Header';
import Footer from './Footer'; // 导入Footer组件function App() {return (<><Header /><main><p>这是博客的正文内容</p></main><Footer /> {/* 使用Footer组件 */}</>);
}export default App;

现在页面结构更完整了:Header(头部)→ main(正文)→ Footer(底部),完全由组件组合而成。

六、动手实践:写一个"用户卡片"组件

让我们综合练习一下,创建一个UserCard.js组件,展示用户信息(头像、姓名、简介),然后在App中使用。

步骤1:创建UserCard.js

// src/UserCard.js
function UserCard() {// 组件内部可以定义数据const user = {name: "李四",avatar: "https://picsum.photos/200", // 随机头像图片bio: "前端学习者,正在学习React组件化"};return (<div className="user-card" style={{ border: '1px solid #ddd', padding: '20px', borderRadius: '8px', maxWidth: '300px' }}>{/* 头像 */}<img src={user.avatar} alt={user.name} style={{ width: '100px', borderRadius: '50%' }}/>{/* 姓名 */}<h3 style={{ color: '#333' }}>{user.name}</h3>{/* 简介 */}<p style={{ color: '#666' }}>{user.bio}</p></div>);
}export default UserCard;

步骤2:在App.js中使用

// src/App.js
import Header from './Header';
import Footer from './Footer';
import UserCard from './UserCard'; // 导入UserCard组件function App() {return (<><Header /><main style={{ padding: '20px' }}><h2>用户列表</h2>{/* 多次使用UserCard组件,体现复用性 */}<UserCard /><UserCard /> {/* 同一个组件可以用多次 */}</main><Footer /></>);
}export default App;

运行效果:

页面会显示两个相同的用户卡片(因为组件复用了),每个卡片有头像、姓名和简介,被边框包裹,样式统一。
这就是组件复用的好处:如果想修改卡片样式,只需要改UserCard.js一个文件,所有卡片都会更新。

七、常见错误与解决办法

  1. 组件名小写导致报错
    错误写法:function userCard() { ... },使用时<userCard />
    原因:React会把小写标签当作普通HTML标签(比如<div>),而HTML中没有userCard标签,所以报错。
    解决:组件名首字母必须大写,function UserCard() { ... },使用时<UserCard />

  2. JSX返回多个根节点
    错误写法:

    function App() {return (<Header /><Footer />);
    }
    

    解决:用<></>包裹:

    function App() {return (<><Header /><Footer /></>);
    }
    
  3. 忘记导出/导入组件
    错误:在UserCard.js中没写export default UserCard,或在App.js中没写import UserCard from './UserCard'
    报错:'UserCard' is not defined
    解决:检查导出和导入语句是否正确,文件名和路径是否匹配(./表示当前目录)。

八、本节课总结

重点回顾:

  1. 组件是"具有独立功能的可复用代码块",页面由组件组合而成,像搭积木;
  2. 函数组件是返回JSX的函数,首字母必须大写,是React推荐的写法;
  3. JSX是React的模板语法,类似HTML但有区别(className、驼峰事件名、样式对象等);
  4. 组件通过export default导出,通过import导入,使用时像HTML标签一样写在JSX中;
  5. 组件的核心优势是复用性、可维护性和协作效率。
http://www.dtcms.com/a/511282.html

相关文章:

  • 国外唯美flash个人网站欣赏建设网银
  • 【NVIDIA-H200-3】3节点all-reduce-三节点扩展的性能边界:NVIDIA H200 24 卡集群 all-reduce 通信效率深度剖析
  • D026 vue3+django 论文知识图谱推荐可视化系统 | vue3+vite前端|neo4j 图数据库
  • 桃浦做网站常德经开区网站官网
  • ODOO数据文件(XML、CSV、SQL)是如何转换并加载到 Odoo 数据库
  • ArcGIS JSAPI 学习教程 - 要素图层(FeatureLayer)分类、分组设置可视化样式(ClassBreaksRenderer)
  • 10天!前端用coze,后端用Trae IDE+Claude Code从0开始构建到平台上线
  • [JavaEE初阶] 传输层协议---UDP 相关笔记
  • 考研408《操作系统》复习笔记,第二章《2.3 进程调度》
  • 网站开发流程有哪几个阶段网站关键词多少个合适
  • GitHub 热榜项目 - 日榜(2025-10-21)
  • 如何提高中药饮片批发业务的市场竞争力?
  • 门户网站建设关键点网站开发编程入门学习
  • 多路由隔离:构建模块化Agent工具服务器
  • [云计算] Classic Network-->VPC: 用SDN和Overlay实现隔离
  • linux shell编程实战 04 条件判断与流程控制
  • 10.21云计算作业
  • 服务器数据恢复—EqualLogic存储硬硬盘坏道,数据恢复有妙招
  • 风险识别不充分会让项目付出什么代价
  • LeetCode 46. 全排列
  • 洛谷 - P13982 数列分块入门 7(线段树解法 - 超详细版)
  • 页面PDF文件格式预览(不使用pdf.js)
  • Prompt Engineering 关键技能:精准掌控 LLM 输出的格式、内容与风格
  • 苹果(IOS)制作开发和发布证书
  • iOS 上架技术支持全流程解析,从签名配置到使用 开心上架 的实战经验分享
  • ISO 15765系列标准在车载诊断系统中的具体应用有哪些?
  • 人体含水量测量体验系统-VR节约用水互动游戏
  • 【ArcGIS软件教程】数据导出、CAD转换、属性表导出、裁剪、空间连接、修复几何
  • XYlease租赁商城小程序
  • 上海做网站建设平面设计线上培训班哪个好