JSX
JSX简介
JSX
是一种用于描述 UI
的 JavaScript
扩展语法,React
使用这种语法描述组件的 UI
。
长期以来,UI
和数据分离一直是前端领域的一个重要关注点。为了解决这个问题,前端领域发明了模板,将 UI
的定义放入模板文件,将数据的逻辑维护在 JS
代码中,然后通过模板引擎,根据数据和模板文件渲染出最终的 HTML
文件或代码片段。大部分前端框架都实现了自己的模板,要使用这些模板,必须学习它们各自的模板语法,而且对于复杂的 UI
,模板语法也很难对其进行清晰的描述。
React
致力于通过组件的概念将页面进行拆分并实现组件复用。React
认为,一个组件应该是具备 UI
描述和 UI
数据的完整体,不应该将它们分开处理,于是发明了 JSX
,作为 UI
描述和 UI
数据之间的桥梁。这样,在组件内部可以使用类似 HTML
的标签描述组件的 UI
,让 UI
结构直观清晰,同时因为 JSX
本质上仍然是 JavaScript
,所以可以使用更多的 JS
语法,构建更加复杂的 UI
结构。
JSX语法
基本语法
JSX
的基本语法和 XML
语法相同,都是使用成对的标签构成一个树状结构的数据,例如:
const element = (
<div>
<h1>Hello, world!</h1>
</div>
)
标签类型
在 JSX
语法中,使用的标签类型有两种:DOM
类型的标签(div
、span
等)和 React
组件类型的标签(在 2.2 节详细介绍组件的概念)。当使用 DOM
类型的标签时,标签的首字母必须小写;当使用 React
组件类型的标签时,组件名称的首字母必须大写。React
正是通过首字母的大小写判断渲染的是一个 DOM
类型的标签还是一个 React
组件类型的标签。例如:
// DOM 类型标签
const element = <h1>Hello, world!</h1>
// React 组件类型标签
const element = <HelloWorld />;
// 二者互相嵌套使用
const element = (
<div>
<HelloWorld />
</div>
)
JavaScript表达式
JSX
可以使用 JavaScript
表达式,因为 JSX
本质上仍然是 JavaScript
。在 JSX
中使用 JavaScript
表达式需要将表达式用大括号 “{}
” 包起来。表达式在 JSX
中的使用场景主要有两个:通过表达式给标签属性赋值和通过表达式定义子组件。例如:
// 通过表达式给标签属性赋值
const element = <MyComponent foo={ 1 + 2 } />
// 通过表达式定义子组件(map虽然是函数,但它的返回值是 JavaScript 表达式)
const todos = ['item1', 'item2', 'item3'];
const element = (
<ul>
{todos.map(message => <Item key={message} message={message} />)}
</ul>
);
注意,JSX
中只能使用 JavaScript
表达式,而不能使用多行 JavaScript
语句。例如,下面的写法都是错误的:
// 错误
const element = <MyComponent foo={const val = 1 + 2; return val; } />
// 错误
let complete;
const element = (
<div>
{
if (complete) {
return <CompletedList />;
} else {
return null;
}
}
</div>
)
不过,JSX
中可以使用三目运算符或逻辑与( &&
)运算符代替 if
语句的作用。例如:
// 正确
let complete;
const element = (
<div>
{
complete ? <CompletedList /> : null
}
</div>
)
// 正确
let complete;
const element = (
<div>
{
complete && <CompletedList />
}
</div>
)
标签属性
当 JSX
标签是 DOM
类型的标签时,对应 DOM
标签支持的属性 JSX
也支持,例如 id
、class
、style
、onclick
等。但是,部分属性的名称会有所改变,主要的变化有:class
要写成 className
,事件属性名采用驼峰格式,例如 onclick
要写成 onClick
。原因是,class
是 JavaScript
的关键字,所以改成 className
;React
对 DOM
标签支持的事件重新做了封装,封装时采用了更常用的驼峰命名法命名事件。例如:
<div id='content' className='foo' onClick={()=> {console.log('Hello, React')}} />
当 JSX
标签是 React
组件类型时,可以任意自定义标签的属性名。例如:
<User name='React' age='4' address='America' >
JSX不是必需的
JSX
语法对使用 React
来说并不是必需的,实际上,JSX
语法只是 React.createElement(component, props, …children)
的语法糖,所有的 JSX
语法最终都会被转换成对这个方法的调用。例如:
//JSX语法
const element = <div className='foo'>Hello, React</div>
// 转换后
const element = React.createElement('div', {className: 'foo'}, 'Hello, React')
虽然 JSX
只是一个语法糖,但使用它创建界面元素更加清晰简洁,在项目使用中应该首选 JSX
语法。