1 什么是JSX
我们将包含在组件return语句后的括号内的所有内容称为 JSX:
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
在后台,React会处理JSX,将它们转换为浏览器可以识别的JS代码。因此,虽然我们编写了 JSX,但是最终会有一个转换的步骤,使它可以被 JavaScript 解析器所识别。
React 这样做的一个主要原因就是:使用 JSX 能更加轻松的开发 UI 界面。 当然了,前提是你必须非常熟悉它。
2 JSX特点
- JSX是一种用来描述组件的外观及工作方式的声明式语法
- 一个组件必须返回一块 (a block of) JSX
- JSX是JavaScript的扩展,允许我们将html、css和JavaScript代码都集成到一个代码块中
- JSX 并不是标准的 JS 语法,而是 JS 的语法扩展,浏览器默认是不识别的,react内置的 @babel/plugin-transform-react-jsx 包,用来解析该语法
3 为何JSX可以更轻松地开发UI页面
如上文所说,JSX 的一个主要作用就是借助它可以非常容易的编写 UI。这是因为在一个 React 组件中,你可以导入其他 React 组件,然后将它们嵌入当前组件以展示它们。
通常情况下,一个文件就是一个 React 组件,这是我们可以非常容易的在其它组件中复用(通过导入的方式)它们的原因。
为了方便学习,我们在 App.js
文件中(也可以在外部,这样就需要导入外部组件)再创建一个名为WelcomeMessage的组件:
function WelcomeMessage() {
return <p>Welcome!</p>
}
这个组件就是一个简单的函数组件,它返回了一行JSX,表示一个p标签。我们将这个函数添加到App组件的JSX代码中,就可以在UI中展示这个组件:
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<WelcomeMessage />
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
)
}
我们称 WelcomeMessage
为子组件,App
为父组件。
我们像使用 HTML 标签一样,添加 <WelcomeMessage />
组件。
这就是 React 组件和 JSX 优雅的地方:我们构建应用程序组件,并且像使用 HTML 标签一样使用它们。
4 JSX和HTML、JavaScript的区别
- JSX使用className属性取代html标签的class属性。这是因为JSX在后台会被处理成JavaScript代码,而class是js中的关键字。
- JSX中所以属性和事件的命名都为驼峰式,如单击事件不是onclick而是onClick,同样的onchange变成了onChange。
- JSX可以内嵌JavaScript代码,只需使用花括号,这在html中是不行的。
- JSX中的任何标签必须闭合,否则会报错。
5 JSX使用
5.1 在JSX中嵌入JS
React 的一大特点就是我们可以非常容易的在 JSX 中嵌入 JavaScript。React 容许我们通过使用大括号的方式在 JSX 中嵌入 JavaScript。
我们可以在 { }
中添加任何 JavaScript 表达式,注意:
- { }中只能包含表达式,而不能包含语句,如if语句等;也就是说{ }中的内容一定是可以返回某个值的
- 每对{ }中只能有一个表达式
如下所示,这是一个在 JSX 中非常常见的表达式。我们编写了一个三元运算符,在其中定义了一个条件语句(message === 'Hello!'
),当条件为真时,我们输出一个值(The message was "Hello!"
);条件为假时,输出另一个值(当前示例中为变量 message
的值):
{
message === 'Hello!' ? 'The message was "Hello!"' : message
}
5.2 列表渲染
使用列表的map方法实现列表渲染:
const fruits = [
{ id: 1, name: 'apple' },
{ id: 2, name: 'banana' },
{ id: 3, name: 'melon' }
]
function App() {
return (
<div className="App">
<ul>
{
fruits.map(item => <li key={item.id}>{item.name}</li>)
}
</ul>
</div>
)
}
注意:
- 需要为遍历项提供key属性,必须是唯一值,React用来内部性能优化使用
- 如果列表中没有提供id这样的值,可以使用
new Date().getTime().toString()
作为key属性值
5.3 条件渲染
条件渲染,即根据不同的条件,渲染出不同的JSX。共有三种方法可以实现条件渲染:&&、三元表达式、条件返回
const Pizza = ({ pizza }) => {
return (
// 模板字符串是js语法,在JSX中需要大括号
<div className={`pizza ${pizza.soldOut ? "sold-out" : ""}`}>
<img src={pizza.photoName} alt={pizza.name} />
<div>
<h3>{pizza.name}</h3>
<p>{pizza.ingredients}</p>
{pizza.soldOut ? <span>SOLD OUT</span> : <span>{pizza.price}</span>}
</div>
</div>
);
};
在上面的代码中,使用三元表达式,当pizza.soldOut
属性为真时,返回JSX<span>SOLD OUT</span>
,否则返回JSX<span>{pizza.price}</span>
。这里返回的JSX同样只能有一个根节点。