JSX是一种像下面这样的语法:
const element = Hello, world!
;
它是一种JavaScript语法扩展,在React中可以方便地用来描述UI。
本质上,JSX为我们提供了创建React元素方法(React.createElement(component, props, ...children)
)的语法糖(syntactic sugar)。上面的代码实质上等价于:
var element = React.createElement(
"h1",
null,
"Hello, world!"
);
JSX本身也是一个表达式,在编译后,JSX表达式会变成普通的JavaScript对象。
你可以在if语句或for循环中使用JSX,你可以将它赋值给变量,你可以将它作为参数接收,你也可以在函数中返回JSX。
例如下面的代码:
function getGreeting(user) {
if (user) {
return Hello, {formatName(user)}!
;
}
return Hello, Stranger.
;
}
上面的代码在if语句中使用JSX,并将JSX作为函数返回值。实际上,这些JSX经过编译后都会变成JavaScript对象。
经过babel会变成下面的js代码:
function test(user) {
if (user) {
return React.createElement(
"h1",
null,
"Hello, ",
formatStr(user),
"!"
);
}
return React.createElement(
"h1",
null,
"Hello, Stranger."
);
}
在JSX中插入JavaScript表达式十分简单,直接在JSX中将JS表达式用大括号括起来即可。例如:
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
};
const element = (
Hello, {formatName(user)}!
);
ReactDOM.render(
element,
document.getElementById('root')
);
上面的代码中用到了函数调用表达式fromatName(user)。
在JavaScript中,表达式就是一个短语,Javascript解释器会将其计算出一个结果,常量就是最简单的一类表达式。常用的表达式有:
需要注意的是,if语句以及for循环不是JavaScript表达式,不能直接作为表达式写在{}中,但可以先将其赋值给一个变量(变量是一个JavaScript表达式):
function NumberDescriber(props) {
let description;
if (props.number % 2 == 0) {
description = even;
} else {
description = odd;
}
return {props.number} is an {description} number;
}
你可以使用引号将字符串字面量指定为属性值:
const element = ;
注意这里的”0”是一个字符串字面量。
或者你可以将一个JavaScript表达式嵌在一个大括号中作为属性值:
const element = ;
这里用到的是JavaScript属性访问表达式,上面的代码将编译为:
const element = React.createElement("img", { src: user.avatarUrl });
首先JSX可以是一个不包含Children的empty tag。如:
const element = ;
JSX也可以像HTML标签一样包含Children:
const element = (
Hello!
Good to see you here.
);
这种写法在生成React元素的时候给我们带来了很大的便利,而且能够更加直观地描述UI。不然我们需要像下面这样创建和上面代码等价的React元素:
const element = React.createElement(
"div",
null,
React.createElement(
"h1",
null,
"Hello!"
),
React.createElement(
"h2",
null,
"Good to see you here."
)
);
tip: React DOM结点使用骆驼拼写法给属性命名
例如:class在JSX中应写作className,tabindex应写作tabIndex。
另外关于JSX的children需要注意的是:
React自定义组件的chilren是不会像固有的HTML标签的子元素那样自动render的,我们看下面的例子:
代码1
class Test extends React.Component {
render() {
return (
Here is a list:
- Item 1
- Item 2
)
}
};
ReactDOM.render(
,
document.getElementById('test')
);
以上代码定义的组件中都是build-in组件,类似div、p、ul、li等。它们中的子元素会直接render出来,像下面这样:
但是如果你使用用户定义组件,比如:
class Test extends React.Component {
render() {
return (
Here is a list:
- Item 1
- Item 2
)
}
};
class Em extends React.Component {
render() {
return ();
}
}
ReactDOM.render(
,
document.getElementById('test')
);
并不能得到跟上面代码1一样的结果,我们得到的只是一个空的div标签:
如果你想得到和代码1一样的结果,需要显示地指定props.children,像下面这样:
class Test extends React.Component {
render() {
return (
Here is a list:
- Item 1
- Item 2
)
}
};
class Em extends React.Component {
render() {
return ({this.props.children});
}
}
ReactDOM.render(
,
document.getElementById('test')
);
得到下面的结果:
在JSX中嵌入接收到的内容是安全的,比如:
const danger = response.potentialDanger;
cosnt ele = {title}
在默认情况下,React DOM会将所有嵌入JSX的值进行编码。这样可以有效避免xss攻击。
我们将以下代码编译后引入html:
class Test extends React.Component {
render() {
let v = "