JSX 看起来像 HTML,但本质上是 JavaScript 的语法扩展。在 JSX 中,你可以通过 {} 嵌入任意合法的 JavaScript 表达式,从而实现动态内容和属性绑定。掌握这些基本写法是写好 React 组件的起点。
表达式嵌入
在 JSX 中,花括号 {} 是 JavaScript 的入口。你可以在其中放入变量、函数调用、运算、三元表达式等任何返回值的表达式,但不能放语句(如 if、for)。
function Greeting() {
const name = '小明';
const getGreeting = () => '你好';
const isLoggedIn = true;
return (
<div>
{/* 嵌入变量 */}
<h1>{name}</h1>
{/* 嵌入函数调用 */}
<p>{getGreeting()},欢迎回来</p>
{/* 嵌入运算 */}
<p>明年你 {parseInt(name.age) + 1} 岁</p>
{/* 三元表达式 */}
<span>{isLoggedIn ? '已登录' : '未登录'}</span>
{/* 注意:if 语句不能直接放在 {} 中,需要提取到函数或外部逻辑 */}
</div>
);
}
常见嵌入场景:
- 字符串拼接:
{Hello, ${user}} - 数组渲染:
{items.map(item => <li key={item.id}>{item.name}</li>)} - 数字格式化:
{price.toFixed(2)} - 布尔值渲染注意:
true、false、null、undefined在 JSX 中不会渲染任何内容,可利用此特性进行条件渲染(如{show && <Component />})
属性绑定
JSX 的属性也使用 {} 绑定动态值。属性名采用驼峰命名法(camelCase),这是与 HTML 最大的不同。
function Avatar() {
const imageUrl = 'https://example.com/avatar.png';
const altText = '用户头像';
const size = 48;
return (
<img
src={imageUrl} // 动态属性
alt={altText}
width={size} // number 类型直接传值
height={size}
tabIndex={0} // HTML 属性名改为驼峰:tabindex -> tabIndex
className="avatar" // class -> className
onClick={() => alert('点击')} // 事件绑定
/>
);
}
属性绑定的几个要点:
- 引号与花括号不能同时使用:要么是字符串字面量(
src="url"),要么是表达式(src={imageUrl}),不能写成src="{imageUrl}"。 - 布尔属性:如
disabled、checked、hidden,直接写属性名表示true,省略表示false。
<button disabled>不可点击</button>
<input checked={isChecked} />
- 展开属性:可以用展开运算符传递多个属性。
const props = { src: imageUrl, alt: '头像', width: 40 };
<img {...props} />
- 值默认为
true:如<input disabled />等价于<input disabled={true} />。
class 写法
在 JSX 中,class 是保留关键字,所以定义 CSS 类名必须使用 className。类名可以是字符串,也可以用模板字符串或第三方库动态拼接。
静态类名:
<div className="card">内容</div>
动态类名(手动拼接):
function Button({ isActive }) {
const baseClass = 'btn';
const activeClass = isActive ? 'btn-active' : '';
return (
<button className={`${baseClass} ${activeClass}`}>
按钮
</button>
);
}
使用 classnames 库(推荐):
npm install classnames
import classNames from 'classnames';
function Button({ isActive, isDisabled }) {
return (
<button
className={classNames('btn', {
'btn-active': isActive,
'btn-disabled': isDisabled
})}
>
按钮
</button>
);
}
classnames 可以接受字符串、对象、数组,并自动过滤掉假值,让类名拼接更清晰。
style 写法
JSX 的内联样式通过一个 JavaScript 对象来定义,属性名采用驼峰命名,值通常是字符串(带单位时也可以用数字)。
基本样式对象:
const divStyle = {
backgroundColor: '#f0f0f0', // background-color -> backgroundColor
fontSize: 16, // 数字默认单位 px,字符串可带单位 '16px'
fontWeight: 'bold',
marginTop: 20,
padding: '8px 12px'
};
<div style={divStyle}>内容</div>
内联动态样式:
function ProgressBar({ percent }) {
return (
<div style={{ width: `${percent}%`, backgroundColor: 'blue' }}>
进度
</div>
);
}
使用 CSS 自定义属性(变量):
<div style={{ '--bg-color': 'blue', backgroundColor: 'var(--bg-color)' }}>
支持 CSS 变量
</div>
注意事项:
- React 不会自动添加浏览器前缀,对于需要
-webkit-等前缀的属性,可以手动添加或使用工具(如 autoprefixer 在构建时处理 CSS 文件)。 - 内联样式不能使用伪类(
:hover)或媒体查询,这些应该使用 CSS 文件或 CSS-in-JS 方案。
小结
JSX 的表达式嵌入、属性绑定、class/style 写法构成了动态 UI 的基础。记住三个关键点:
- JS 表达式用
{}包裹,可以放变量、运算、函数调用,但不能放语句。 - 属性名驼峰命名,
class变className,事件用onXxx。 - 样式用对象,属性名驼峰,数值无单位默认
px。
这些规则熟练后几乎可以条件反射般地编写,是 React 日常开发的基本功。