一、组件化思维入门:什么是组件化、为什么需要组件化、React组件的基本概念、从HTML到JSX的思维转变
1.1 什么是组件化?说白了就是搭积木
我记得刚入行那会儿,写前端页面就是一把梭——HTML、CSS、JavaScript全揉在一个文件里。一个页面几千行代码,改个按钮颜色得翻半天。后来接触了组件化,才恍然大悟:这不就是搭积木吗?
组件化,就是把页面拆成一个个独立、可复用的小块。每个小块只管自己的事,互不干扰。比如一个搜索框,它自己管自己的样式、交互、数据。你把它往页面上一放,它就能工作。
核心要点:组件 = 结构 + 样式 + 行为 的封装体
举个例子,一个典型的页面可以拆成这样:
页面
├── 头部导航(Header)
│ ├── Logo
│ ├── 导航菜单(NavMenu)
│ └── 用户信息(UserInfo)
├── 内容区(Content)
│ ├── 文章列表(ArticleList)
│ │ └── 文章卡片(ArticleCard)
│ └── 侧边栏(Sidebar)
│ ├── 搜索框(SearchBox)
│ └── 标签云(TagCloud)
└── 底部(Footer)
你看,每个部分都是独立的组件。它们可以单独开发、单独测试、单独维护。这就是组件化的核心思想。
1.2 为什么需要组件化?我踩过的坑告诉你
说实话,我刚做React时也觉得组件化麻烦。一个简单的按钮,非得拆成组件,写一堆props,图啥?直到我在项目中遇到了这些事:
- 改一处,崩一片:一个全局的CSS类名,改了个颜色,结果三个页面样式全乱了
- 代码复制粘贴:同样的表单校验逻辑,在五个页面里各写了一遍,后来要改校验规则,得改五个地方
- 新人上手慢:一个页面几千行代码,新同事看了一周都不敢动
组件化能解决这些问题,原因有三:
| 痛点 | 组件化方案 |
|---|---|
| 样式冲突 | 组件内样式隔离,互不影响 |
| 重复代码 | 组件复用,一处修改处处生效 |
| 维护困难 | 组件职责单一,易于理解和修改 |
我的经验:组件化不是银弹。别为了组件化而组件化。如果一个组件只在一个地方用一次,而且逻辑简单,那写成内联代码也没问题。我见过有人把一行文本都拆成组件,那就过度设计了。
1.3 React组件的基本概念
React里的组件,本质上就是一个函数或一个类。它接收输入(props),返回输出(JSX)。就这么简单。
来看两种最常见的组件写法:
函数组件(推荐)
// 函数组件:就是一个普通的JavaScript函数
function Greeting(props) {
return <h1>你好,{props.name}!</h1>;
}
// 使用组件
<Greeting name="张三" />
类组件(历史遗留)
// 类组件:继承React.Component
class Greeting extends React.Component {
render() {
return <h1>你好,{this.props.name}!</h1>;
}
}
注意:现在新项目基本都用函数组件了。类组件你了解就行,面试可能会问,但实际开发中我建议直接用函数组件 + Hooks。我曾经接手过一个全是类组件的项目,那代码量...嗯,你懂的。
组件有三个核心概念:
- Props:组件的输入参数,由父组件传递,子组件不能修改
- State:组件的内部状态,可以改变,改变后组件会重新渲染
- 生命周期:组件从创建到销毁的过程(函数组件用Hooks模拟)
1.4 从HTML到JSX的思维转变
这是很多初学者最不适应的地方。你想想看,写了那么多年HTML,突然告诉你「以后在JavaScript里写HTML」,是不是觉得怪怪的?
我第一次看到JSX时,心里想的是:「这什么玩意儿?HTML和JS混在一起,不违背关注点分离原则吗?」
后来我才明白,React的哲学是:关注点分离不是技术分离,而是职责分离。一个组件同时包含它的结构和行为,这才是真正的「关注点在一起」。
HTML vs JSX 的差异
| HTML | JSX |
|---|---|
| class="xxx" | className="xxx" |
| for="xxx" | htmlFor="xxx" |
| style="color: red" | style={ { color: 'red' } } |
| onclick="handleClick()" | onClick={handleClick} |
| 单标签必须闭合 | 所有标签必须闭合:<br /> |
| 可以写注释 <!-- --> | 必须用JS注释 {/* */} |
思维转变的关键:把HTML看作JavaScript的扩展,而不是独立的模板语言。JSX最终会被编译成React.createElement()调用,本质上就是JavaScript。
来看一个完整的例子,感受一下从HTML到JSX的转变:
// HTML写法
<div class="user-card">
<img src="avatar.jpg" class="avatar" />
<h2>张三</h2>
<p class="bio">前端工程师</p>
<button onclick="follow()">关注</button>
</div>
// JSX写法
function UserCard() {
const [isFollowed, setIsFollowed] = useState(false);
return (
<div className="user-card">
<img src="avatar.jpg" className="avatar" />
<h2>张三</h2>
<p className="bio">前端工程师</p>
<button onClick={() => setIsFollowed(!isFollowed)}>
{isFollowed ? '已关注' : '关注'}
</button>
</div>
);
}
你发现没?JSX里可以直接写JavaScript表达式(用花括号包裹),可以绑定事件,可以控制状态。这就是组件化的威力——结构、样式、行为,全在一个组件里,高内聚、低耦合。
避坑指南:我曾经在JSX里写if语句,结果报错了。记住,JSX里只能写表达式,不能写语句。要用条件渲染,请用三元运算符或逻辑与:
// 正确
{isLoggedIn ? <UserPanel /> : <LoginButton />}
{isAdmin && <AdminPanel />}
// 错误
{if (isLoggedIn) { return <UserPanel /> }}
小结
这一章我们聊了:
- 组件化就是搭积木,把页面拆成独立的小块
- 组件化能解决样式冲突、代码重复、维护困难三大痛点
- React组件就是函数或类,接收props返回JSX
- JSX是HTML的JavaScript化,记住那几个差异点就行
下一章,我们会深入组件的核心——Props和State。到时候我会分享一个我踩过的坑,关于state更新不及时导致线上bug的...嗯,那故事挺有意思的。