JSX 简介
JSX 是一个语法扩展,它允许你在 JavaScript 文件中编写类似 HTML 的代码。它是 React 的核心特性之一。
JSX 基础语法
1. JSX 元素
// JSX 元素必须有一个根元素
const element = (
<div>
<h1>Hello, World!</h1>
<p>这是第一个 JSX 示例</p>
</div>
);
// 使用 Fragment 避免额外的 div
const element = (
<>
<h1>Hello, World!</h1>
<p>这是第一个 JSX 示例</p>
</>
);
2. 在 JSX 中嵌入表达式
使用大括号 {} 可以在 JSX 中嵌入任何 JavaScript 表达式:
const name = 'React';
const element = <h1>Hello, {name}!</h1>;
// 也可以调用函数
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = { firstName: '张', lastName: '三' };
const element = <h1>Hello, {formatName(user)}!</h1>;
3. JSX 属性
// 使用引号传递字符串字面量
const element = <div tabIndex="0"></div>;
// 使用大括号嵌入 JavaScript 表达式
const element = <img src={user.avatarUrl}></img>;
// 注意:不能在 JSX 中使用引号和大括号同时定义属性
// 错误 ❌
const element = <div className="header {className}"></div>;
// 正确 ✅
const element = <div className={`header ${className}`}></div>;
JSX 是表达式
编译后,JSX 表达式会变成普通的 JavaScript 函数调用:
// JSX 写法
const element = (
<div className="sidebar">
<h1>标题</h1>
</div>
);
// 编译后的 JavaScript
const element = React.createElement(
'div',
{ className: 'sidebar' },
React.createElement('h1', null, '标题')
);
JSX 中的点表示法
可以使用点表示法来引用 React 组件:
import MyComponents from './MyComponents';
const component = <MyComponents.DatePicker color="blue" />;
条件渲染
1. 元素变量
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>欢迎回来!</h1>;
}
return <h1>请先登录</h1>;
}
2. 三元运算符
function Greeting({ isLoggedIn }) {
return (
<div>
{isLoggedIn ? <h1>欢迎回来!</h1> : <h1>请先登录</h1>}
</div>
);
}
3. 逻辑与运算符 &&
function Mailbox({ unreadMessages }) {
return (
<div>
<h1>你好!</h1>
{unreadMessages.length > 0 &&
<h2>
你有 {unreadMessages.length} 条未读消息
</h2>
}
</div>
);
}
列表渲染
1. 使用 map()
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) => (
<li key={number.toString()} value={number}>
{number}
</li>
));
return <ul>{listItems}</ul>;
2. Keys
Keys 帮助 React 识别哪些元素改变了:
// 使用 id 作为 key(推荐)
const todoItems = todos.map((todo) => (
<li key={todo.id}>
{todo.text}
</li>
));
// 如果没有 id,可以使用索引(不推荐)
const todoItems = todos.map((todo, index) => (
<li key={index}>
{todo.text}
</li>
));
表单处理
受控组件
function NameForm() {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
const handleSubmit = (event) => {
alert('提交的名字: ' + value);
event.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<label>
名字:
<input
type="text"
value={value}
onChange={handleChange}
/>
</label>
<button type="submit">提交</button>
</form>
);
}
💡 最佳实践
- 始终关闭标签:JSX 中所有标签都必须闭合
- 使用 camelCase 命名:
class→className,tabindex→tabIndex - 条件渲染使用 &&:简洁明了
- 列表必须有 key:使用稳定的标识符
- 避免内联样式对象:提取到常量或样式表
🎯 练习
- 创建一个显示用户列表的组件
- 实现一个可以切换显示/隐藏的功能
- 编写一个表单,收集用户信息
下一节我们将学习 组件的生命周期,理解 React 组件的完整生命周期!