深入了解React的概念之一: JSX

一、什么是JSX

使用JSX声明一个变量(React 当中的元素):

const element = 

Hello, world!

;

JSX是一种 JavaScript 的语法扩展。 我们推荐在 React 中使用 JSX 来描述用户界面。JSX 乍看起来可能比较像是模版语言,但事实上它完全是在 JavaScript 内部实现的。

二、为什么要使用JSX

传统的 MVC 是将模板放在其他地方,比如

2. 外联方式载入

即将 JSX 代码单独放在一个.jsx 文件中。

ReactDOM.render(
     

hello hangge.com

, document.getElementById('example') );

然后在页面上通过下面的方式引入这个 .jsx 文件。



四、在 JSX 中使用表达式

可以任意地在 JSX 当中使用 JavaScript 表达式,在 JSX 当中的表达式要包含在大括号里(个人理解就是写在JS里的HTML里的JS需要{}大括号)。

// 定义一个函数,返回传入的名字的拼写后的结果
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}
// 定义一个数据类型为对象的常量
const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};
// 使用JSX语法来定义一个html标签(所以element为小写开头)
const element = (
  

Hello, {formatName(user)}!

); // 渲染这个html标签 ReactDOM.render( element, document.getElementById('root') );

注意:

  1. 我们书写 JSX 的时候一般都会带上换行和缩进,这样可以增强代码的可读性。
  2. 与此同时,我们同样推荐在 JSX 代码的外面扩上一个小括号,这样可以防止 分号自动插入 的 bug。


五、JSX 本身其实也是一种表达式

在编译之后呢,JSX 其实会被转化为普通的 JavaScript 对象。

这也就意味着,你其实可以在 if 或者 for 语句里使用 JSX,将它赋值给变量,当作参数传入,作为返回值都可以:

// 定义一个函数,如果有传参数进来就把名字拼写好返回,否则就返回陌生人
function getGreeting(user) {
  if (user) {
    return 

Hello, {formatName(user)}!

; } return

Hello, Stranger.

; }


六、JSX 属性

  • 你可以使用引号来定义以字符串为值的属性:
const element = 
;
  • 也可以使用大括号来定义以 JavaScript 表达式为值的属性:
const element = ;

切记使用了大括号包裹的 JavaScript 表达式时就不要再到外面套引号了。JSX 会将引号当中的内容识别为字符串而不是表达式。(不要src="{user.avatarUrl}",会以为src为{user.avatarUrl})


七、JSX 嵌套

如果 JSX 标签是闭合式的,那么你需要在结尾处用/>, 就好像 XML/HTML 一样:

const element = ;

JSX 标签同样可以相互嵌套:(当换行和缩进的时候,使用括号包住它们)

const element = (
  

Hello!

Good to see you here.

);

警告:
因为 JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小驼峰命名 来定义属性的名称,而不是使用 HTML 的属性名称。(概括就是: JSX使用小驼峰命名定义属性的名称)
例如,class 变成了 className,而 tabindex 则对应着 tabIndex


八、JSX 防注入攻击

你可以放心地在 JSX 当中使用用户输入:

const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = 

{title}

;

React DOM 在渲染之前默认会 过滤 所有传入的值。它可以确保你的应用不会被注入攻击。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(跨站脚本) 攻击。

九、HTML 转义

React 会将所有要显示到 DOM 的字符串转义,防止 XSS。所以如果 JSX 中含有转义后的实体字符比如 © (©) 最后显示到 DOM 中不会正确显示,因为 React 自动把 © 中的特殊字符转义了。有几种解决办法:

  • 直接使用 UTF-8 字符 ©
  • 使用对应字符的 Unicode 编码,查询编码
  • 使用数组组装
    {['cc ', ©, ' 2015']}
  • 直接插入原始的 HTML


十、JSX 代表 Objects

Babel 转译器会把 JSX 转换成一个名为React.createElement()的方法调用。

下面两种代码的作用是完全相同的:

const element = (
  

Hello, world!

);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React.createElement() 这个方法首先会进行一些避免bug的检查,之后会返回一个类似下面例子的对象:

// 注意: 以下示例是简化过的(不代表在 React 源码中是这样)
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
};

这样的对象被称为 “React 元素”。它代表所有你在屏幕上看到的东西。
React 通过读取这些对象来构建 DOM 并保持数据内容一致。

十一、注释

在 JSX 里使用注释也很简单,就是沿用 JavaScript,唯一要注意的是在一个组件的子元素位置使用注释要用 {} 包起来。

var content = (
  
);


十二、自定义 HTML 属性

如果在 JSX 中使用的属性不存在于 HTML 的规范中,这个属性会被忽略。如果要使用自定义属性,可以用 data- 前缀。

可访问性属性的前缀 aria- 也是支持的。

支持的标签和属性

如果你要使用的某些标签或属性不在这些支持列表里面就可能被 React 忽略,必须要使用的话可以提 issue,或者用前面提到的 dangerouslySetInnerHTML

十三、属性扩散

有时候你需要给组件设置多个属性,你不想一个个写下这些属性,或者有时候你甚至不知道这些属性的名称,这时候 spread attributes 的功能就很有用了。

比如:

var props = {};
props.foo = x;
props.bar = y;
var component = ;

props 对象的属性会被设置成 Component 的属性。

属性也可以被覆盖:

ar props = { foo: 'default' };
var component = ;
console.log(component.props.foo); // 'override'

写在后面的属性值会覆盖前面的属性。

关于 ... 操作符
The ... operator (or spread operator) is already supported for arrays in ES6. There is also an ES7 proposal for Object Rest and Spread Properties.


参考资料

  1. React 官方中文文档
  2. React 中文文档
  3. React - JSX语法详解(附样例)

你可能感兴趣的:(深入了解React的概念之一: JSX)