第四节:JSX

56 阅读4分钟

JSX

本质上认识JSX

JSX = JavaScript and XML它有如下特点

  1. 编译后可以运行咋JS环境
  2. 使用标签上的语法定义一个变量
  3. 可以在标签内部使用JS语法
{new Date().toLocaleTimeString()}

本质上JSX就是调用React.createElement的语法糖,是声明React元素的另一种高效方式,不仅允许开发者在JS中编写DOM结构,还可以在DOM节点插入JS表达式,从而更简单、快速的实现数据绑定。

React.creatElement解析

作用:

  • 创建React元素

参数:

  • component:组件名,可以是字符串表示的HTML元素,也可以是变量名表示的React.Component子类
  • props:组件的属性对象
  • children:组件的子节点

使用JSX:

const element = (
    <h1 id = "tryrun">hello,world!</h1>
)

等价于不使用JSX

const element = React.createElement(
   'h1',
   {id:"tryrun1"},
   'hello,world!'
);   

通过对比我们也能发现使用JSX有更加友好的标签方式创建React元素,并且代码结构更加清晰,提高代码的可读性。

引入JS的优点

引入JSX具有以下优点:

  • JSX被编译为JS代码时进行了优化,相比之下执行更快
  • JSX是类型安全的,在编译过程中就能发现错误
  • 通过在不同平台上提供解释器,让跨平台成为可能,于是诞生了React Native

JSX的使用

JSX编写DOM结构

利用JSX编写DOM节点可以使用原生的HTML标签也可以使用React组件。规定首字母大写的是React组件,首字母小写的是HTML标签

标签
ReactDOM.render( 
<div className="foo" />, 
document.getElementById("app") );
组件
ReactDOM.render(
<MyComponent />, 
document.getElementById("app") );

JSX声明react元素的注意事项

  • 必须有且只有一个根节点 反例:
const ele = ( 
<h1>没有一个根标签包裹</h1>  
<p>与 h1 标签同级</p>
);
  • JSX中的所有标签都必须正确闭合。
const ele = <input type="text">;
  • 标签的镶嵌必须符合W3C标准。
  • 一些html属性是JS的保留关键字,需要使用React另外规定的属性代替,否则会给出相应警告。例如要用className替代clas 使用htmlFor替代for
  • 当JSX代码出现换行的情况,建议使用()将代码包裹起来,可以防止分号自动插入的Bug

在JSX里嵌入JS表达式

在使用JSX创建React元素时,可以使用插槽符合{{}}形式插入任何有效的JS表达式。但是每个大括号里只能包含单个表达式。

let number = 98;
let ok = true;
let message = "JavaScript in JSX"; 
ReactDOM.render(
<div>
<p> { number + 1 } </p>  
<p> { ok ? "Yes" : "No" } </p>    
<p> { message.split("").reverse().join("") } </p>  
</div>,    
document.getElementById("app") 
);

JSX中表达式的返回值

JSX里的表达式的返回值会作为React的子节点,所以对于JS表达式里的返回值需要做限制。

  • 允许:numberstringArrayReact元素,其中Array会被扁平化,数组的每一项都将作为子节点渲染。
  • 不允许:普通的JavaScript对象、function函数
let ele = {a : 1, b : 2};
ReactDOM.render(
<div>         
<p> { ele } </p>   
</div>,     
document.getElementById("app") );
  • 无渲染:nullundefinedbooleansymbol

JSX本身也是一个表达式

JSX也是一个JS表达式:被转换为普通JS函数调用,并且对其取值后得到JS对象。因此可以在if或者for语句中使用JSX,将JSX赋值给变量,把JSX当中参数传入,或从函数中返回JSX。

JSX中的注释

注意两点:

  • 在React元素的子节点位置使用注释要用{}包起来,且只能使用多行注释符/**/
  • 在React元素的属性位置可以完全使用JavaScript注释方式

JSX属性

JSX属性的类型及绑定方式

在JSX中给React元素绑定的属性可以分为四种:

  1. 存在于HTML规范中的属性,如:idclassNamesrc
  2. 给DOM元素绑定的自定义属性,建议使用data-前缀的形式
  3. React规定的特殊属性,如keyrefdangerouslySetInnerHTML
  4. 用于给组件传值的props属性

绑定属性值的方式:

  • 使用引号,将属性值指定为字符串字面量
let ele = <div id="wrap" className="w-100"></div>;
  • 使用大括号,将属性值指定为JavaScript表达式
let width = 160; let ele = <div id="wrap" className={"w-" + width}></div>;

注:使用{}计算属性值时,会对表达式的返回值调用toString方法再赋值

特殊的style属性

给元素设置style属性时,只能使用大括号的形式插入JavaScript对象:

const w = 200;
const ele = (
<div        
style={{width: w + "px", height: "100px", backgroundColor: "#ffc5a1"}}     ></div> 
);

解析:

  1. 第一个{}表示JSX语法开始,第二个{}表示style接受的是一个对象键值对,且不会调用toString方法将其转换为字符串"[Object Object]"
  2. 若使用小驼峰的写法backgroundColor不需要写成字符串的形式,若采用烤串型background-color则需要使用字符串形式:"background-color":"#ffc5a1"

与HTML之间的属性差异

  • JavaScript:保留关键字:使用className替代class,使用htmlFor替代for
  • 使用小驼峰指定属性名
  • 在表单元素上:存在valuedefaultValuecheckeddefaultChecked,他们有不同意义