JSX概述
React的核心机制之一就是虚拟DOM:可以在内存中创建的虚拟DOM元素。React利用虚拟DOM来减少对实际DOM的操作从而提升性能。类似于真实的原生DOM,虚拟DOM也可以通过JavaScript来创建
var child1 = React.createElement('li', null, 'First Text Content');
var child2 = React.createElement('li', null, 'Second Text Content');
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
使用这样的机制,我们完全可以用JavaScript构建完整的界面DOM树,正如我们可以用JavaScript创建真实DOM。但这样的代码可读性并不好,于是React发明了JSX,利用我们熟悉的HTML语法来创建虚拟DOM
var root =(
<ul className="my-list">
<li>First Text Content</li>
<li>Second Text Content</li>
</ul>
);
这两段代码是完全等价的,后者将XML语法直接加入到JavaScript代码中,让你能够高效的通过代码而不是模板来定义界面。之后JSX通过翻译器转换到纯JavaScript再由浏览器执行。
总而言之,JSX是React的核心组成部分,它使用XML标记的方式去直接声明界面,界面组件之间可以互相嵌套。可以将JSX理解为在JS中编写与XML类似的一种定义带DOM结构的语法,它的目的是通过babel编译器将这些JSX标记编译成标准的JS语言。
JSX语法
JSX的语法很简单,JSX本身就和XML语法类似,可以定义属性以及子元素。需要注意语法中的标签必须都是闭合或半闭合的标签使用大括号来加入JavaScript表达式。另外,对于自己定义的组件,其标签的首字母要大写。例如
<Person name={window.isLoggedIn ? window.name : ''} />;
JSX中的if-else
在JSX中无法使用 if-else 语句,因为 JSX 只是函数调用和对象创建的语法糖,不过在JSX语法中可以使用三元运算符。
{courseDetail.isLive?
(<span className="course-img-cover">
<span className="u-play-icon"></span>
<span className="cover-text">进入视频直播</span>
</span>):''}
如果三元操作表达式不够健壮,你也可以使用 if 语句来决定应该渲染什么组件
if(statisticsList && statisticsList.length){
statisticsListHtml = <div className="statistics-table">
<Table columns={this.data.columns} dataSource={statisticsList}></Table>
</div>
} else {
statisticsListHtml = <div className="statistics-table">
<Loading ajaxState={this.state.listAjaxState} error={this.state.listError} type="personal"/>
</div>
}
JSX中的循环
JSX语法中可以使用js中的map函数实现循环操作
{rankList[rankType].map((item,index) => {
return <li key={index} className="rank-item">
<div className="rank-img">
<img src={item.picUrl} width="50" height="50"/>
</div>
</li>
}
JSX中的事件绑定
React事件的绑定方法在写法上与原生的HTML事件监听器属性很相似,并且含义和触发场景都是一致的。但是在JSX中必须使用驼峰的形式来书写事件的属性名,而其属性值可以是任意类型。
<button onClick={this.handleClick}>test</button>
JSX的注意事项
总结一下使用JSX时需要注意的地方
- 因为JSX为JS的语法糖,class和for作为JS的特殊特殊关键字,在JSX中使用className和htmlFor代替
- 在JSX中如果需要将html字符串转化为dom元素,不能使用pre标签,使用dangerouslySetInnerHTML = {{__html: htmlStr}}属性实现,不过需要注意xss攻击问题
<div className="message-detail" dangerouslySetInnerHTML={{__html: messageInfo.messageContent}}></div>
- 在JSX中样式的处理方法,如果需要在JSX的元素中加入style字符串,使用方法为
<ul className="rank-cont" ref="rankCont" style={{height:10,width: 10}}></ul>