JSX 语法的本质目的是为了使用基于 xml 的方式表达组件的嵌套,保持和 HTML 一致的结构,语法上除了在描述组件上比较特别以外,其它和普通的 Javascript 没有区别。 并且最终所有的 JSX 都会编译为原生 Javascript。

JSX = JavaScript XML
JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

特点

  • 类XML语法:有固定的标签开启和闭合。这能让复杂的树更易于阅读,优于方法调用和对象字面量的形式。
  • 增强JS语义:不是模板,模板与页面是分离的,是字符串,而JSX是JS语法本身,有更多的扩展
  • 结构清晰
  • 抽象程度高:屏蔽了手动的DOM操作,跨平台-JSX是独立于平台的语法,React在不同的平台提供解释器
  • 代码模块化:MVC是纵向切分,React是横向切分,大项目由众多小项目组成

HTML组件 与 React组件

HTML组件和HTML中原生的组件一样,而React组件是自定义的组件
JSX 中约定以大小写字母开头来区分,组件一般以大写字母开头

//JSX中支持绝大部分HTML标签
<label className="lb" htmlfor="uName" style={{color:'red'; font-size:'14px'}}></label> // 组件类
class MyComponent extends React.Component{
render(){
return <div>Customer Component:{this.props.name}</div>
}
} React.render(<MyComponent name="propsText"/>, document.getElementById('d1'))

由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。

JSX转换器

JSX 把类 XML 的语法转成纯粹 JavaScript,XML 元素、属性和子节点被转换成 React.createElement 的参数。

React.createElement(HTML标签名称/父组件,标签属性,子元素)

//JSX语法
<label className="xxx" htmlFor="input">content</label> //转换后
React.createElement('label', {className: 'xxx', htmlFor: 'input'}, 'content')

命名空间式组件

如果一个组件拥有多个子组件,可以将子组件做为父组件的属性

// 命令空间式组件
class FormRoot extends React.Component{
render(){
return(
<div>
FromRoot
{this.props.children}
</div>
)
}
} class Row extends React.Component{
render(){
return(
<div className="box" style={{color:'#3f3', height:'auto'}}>
Form Row {this.props.children}
</div>
)
}
}
class Label extends React.Component{
render(){
return <div className="box" style={{color:'#f90'}}> Form Label </div>
}
}
class Input extends React.Component{
render(){
return <div className="box" style={{color:'red'}}> Form Input </div>
}
} FormRoot.Row = Row;
FormRoot.Label = Label;
FormRoot.Input = Input; class APP extends React.Component{
render(){
return (
<div className="box" style={{height:'auto'}}>
<FormRoot>
<FormRoot.Row>
<FormRoot.Label />
<FormRoot.Input />
</FormRoot.Row>
</FormRoot>
</div>
)
}
} React.render(<APP />, document.getElementById('box1'));

Javascript表达式

在JSX语法中,使用{}标识内部是JS表达式
JSX是HTML和JavaScript混写的语法,当遇到<,JSX就当HTML解析,遇到{就当Javascript解析

render(){
return <Person name={window.isLoggedIn ? window.name : ''} />
}

属性表达式

在使用 JS表达式 做为属性时,必须使用 {} 包含在内,不可使用 ""

render(){
return <div className={2 > 1 ? 'class-a' : 'class-b'}>content</div>
}

子表达式

组件嵌套中同样可以使用 JS表达式 来处理组件的显示逻辑

render(){
return <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>
}

注释 (Comments)

注释作用于源码,对源码做说明,不会出现实在渲染后的DOM中

var content = (
<div className="box">
{/* 一般注释, 用 {} 包围 */}
<span
/* 多

注释 */
name={2>1 ? '2' : '1'} // 行尾注释
>{2>1 ? '2' : '1'}</span>
</div>
); React.render(content, document.getElementById('box1'));

延展属性(Spread Attributes)

组件的属性应当在组件初始化时指定,而不应在初始化以后指定,这样会导致 props 对象的修改不可预测, React 也不能帮助检查属性类型。

//better
<Component foo={x} bar={y} /> //bad
<Component />
Component.props.foo = x;
Component.props.bar = y;

属性延展是将一个对象添加为组件的属性的语法糖
操作符 ... 是ES6中的延展语法(spread operator),可以将一个对象展开

var props = { foo: x, bar: y };
var component = <Component { ...props } foo={'override'}>; // 等价于
var component = <Component foo={x} bar={y} />;

注意:后面相同的属性覆盖掉前面的属性

JSX陷阱

style属性

style属性是用两个 { 包含的,最外层的 { 表示内部是一个JS表达式,里面的 { 表示是一个JS对象字面量

render(){
return (
<div style={{color:'red'}}>
xxxxx
</div>
) }

HTML转义

React 默认会转义所有字符串,为了防止各种 XSS 攻击。
可使用 __html 进行转义

var content='<strong>content</strong>';

React.render(
<div>{content}</div>,
document.body
);
//页面直接输出: <strong>content</strong> var content='<strong>content</strong>'; React.render(
<div dangerouslySetInnerHTML={{__html: content}}></div>,
document.body
); //输出加粗后的: content

标签闭合

在JSX中,无论是单标签还是成对的双标签,必有闭合符,不然会报错

render(){
return(
<div>
<img src="xxx.jpg" />
<button>确认<button/>
</div>
)
}

根节点

自定义组件在render()函数中返回的组件内容,必须有一个根节点包含起来

// bad
function render() {
return (<p> .... </p>
<p> .... </p>)
}
// good
function render() {
return (<p> .... </p>)
} function render() {
return (
<div>
<p> .... </p>
<p> .... </p>
</div>
)
}

循环遍历

通过循环遍历出生成的组件集合,在循环时一定要加上key

render(){
return (
<p>
{arr.map(function(it,i) {
return <span key={i}> {it} </span>
})}
</p>
)
}

IF-ELSE

在JSX中是不可以直接在{}中加入if-else

  • 使用 三元操作符 来替代 if-else,或者将复杂的操作在JSX外面使用JS去处理
  • 使用闭包自执行函数
//错误的写法
// var App = (
// <div>
// {
// if(2>1){
// <p>SUCCESS</p>
// }else{
// <p>FAILURE</p>
// }
// }
// </div>
// ); var App = (
<div className="box">
{
2>1 ? <p>SUCCESS</p> : <p>FAILURE</p>
}
</div>
); React.render(App, document.getElementById('box1')) // 或者
// 将逻辑抽离到JS中执行
var loginButton;
if (loggedIn) {
loginButton = <LogoutButton />;
} else {
loginButton = <LoginButton />;
} return (
<nav>
<Home />
{loginButton}
</nav>
); // 或者
// 使用闭包自执行函数
var App = (
<div className="box">
{
(()=>{
if(2>1){
return <p>SUCCESS</p>
}else{
return <p>FAILURE</p>
}
})()
}
</div>
);

Show-Hide

class App extends React.Component{
constructor(){
super()
this.state={
showHide: true
}
}
render(){
return (
<div className="box" style={{heigth:'auto'}}>
<div className={this.props.showHide?"":"hide"}>通过Props可以初始化这段文字的显示隐藏</div>
<div className={this.state.showHide?"":"hide"}>通过State可以改变这段文字的显示隐藏</div>
<input type="button"
value={this.state.showHide ? '隐藏':'显示'}
onClick={()=>{ this.setState({showHide : !this.state.showHide}) }}
/>
</div>
)
}
} React.render(<App showHide={true} />, document.getElementById('box1'))

Switch-Case

return (
<section>
<h1>Color</h1>
<h3>Name</h3>
<p>{this.state.color || "white"}</p>
<h3>Hex</h3>
<p>
{(() => {
switch (this.state.color) {
case "red": return "#FF0000";
case "green": return "#00FF00";
case "blue": return "#0000FF";
default: return "#FFFFFF";
}
})()}
</p>
</section>
);

Loop:循环

var rows = [];
for (var i=0; i < numrows; i++) {
rows.push(<ObjectRow key={i}/>);
} render(){
return (<tbody>{rows}</tbody>);
}

相关示例

[转] ReactJS之JSX语法的更多相关文章

  1. 2.ReactJS基础(虚拟DOM,JSX语法)

    将脚手架(create-react-app)创建的todolist项目精简为hello world示例 即,删除自动生成的样式文件.logo.svt.App.test.js.serviceWorker ...

  2. 前端笔记之React(一)初识React&组件&JSX语法

    一.React项目起步配置 官网:https://reactjs.org/ 文档:https://reactjs.org/docs/hello-world.html 中文:http://react.c ...

  3. JSX语法简介

    React的核心机制之一就是可以在内存中创建虚拟的DOM元素.React利用虚拟DOM来减少对实际DOM的操作从而提升性能. JSX简介 JSX就是Javascript和XML结合的一种格式.Reac ...

  4. 22-React JSX语法

    React JSX语法 JSX只是一个语法糖,每一个XML标签都会被JSX转换工具转换成纯Javascript代码,当然你想直接使用纯Javascript代码写也是可以的,只是利用JSX,组件的结构和 ...

  5. React JSX语法说明

    原文:http://my.oschina.net/leogao0816/blog/379487 什么是JSX? 在用React写组件的时候,通常会用到JSX语法,粗看上去,像是在Javascript代 ...

  6. Webstorm 不识别es6 import React from ‘react’——webstorm不支持jsx语法怎么办

    2016-10-31更新 webstorm不支持es6语法怎么办? webstorm不支持jsx语法怎么办? 参考:webstorm不支持jsx语法怎么办 I spent ages trying to ...

  7. 【JAVASCRIPT】React学习-JSX 语法

    摘要 react 学习包括几个部分: 文本渲染 JSX 语法 组件化思想 数据流 JSX 语法 1. 定义 JSX 是javascript + xml 的合集,我们可以将javascript 与 ht ...

  8. 2. React JSX语法及特点介绍

    什么是JSX         JSX 是一种类 XML 语言,全称是 JavaScript XML .React 可以不使用 JSX来编写组件,但是使用JSX可以让代码可读性更高.语义更清晰.对 Re ...

  9. react的jsx语法

    在webpack.config.js中配置解析的loader { test:/\.jsx?$/, use:{ loader:"babel-loader", options:{ pr ...

随机推荐

  1. 题解-BOI 2004 Sequence

    Problem bzoj & Luogu 题目大意: 给定序列\(\{a_i\}\),求一个严格递增序列\(\{b_i\}\),使得\(\sum \bigl |a_i-b_i\bigr|\)最 ...

  2. hibernate框架学习之Session管理

    Session对象的生命周期 lHibernate中数据库连接最终包装成Session对象,使用Session对象可以对数据库进行操作. lSession对象获取方式: •加载所有配置信息得到Conf ...

  3. BZOJ 3620: 似乎在梦中见过的样子

    似乎在梦中见过的样子.... 一道水题调了这么久,还半天想不出来怎么 T 的...佩服自己(果然蒟蒻) 这题想想 KMP 但是半天没思路瞟了一眼题解发现暴力枚举起始点,然后 KMP 如图: O( n2 ...

  4. nginx 负载 问题

    1 如果使用ip_hash,nginx必须为最前端负载均衡,如果大网环境部署,基本无法实现,内网还可以使用 2 如果不使用ip_hash,则要考虑session问题,可以使用memcached与tom ...

  5. mysql:赋予用户权限、查看及修改端口号

    一.mysql 赋给用户权限 grant all privileges on *.* to joe@localhost identified by '1'; flush privileges; 即用u ...

  6. 【原创】大叔经验分享(29)cdh5使用已存在的metastore数据库部署hive

    cdh5.16.1使用的hive版本是hive-1.1.0+cdh5.16.1+1431,详见:https://www.cloudera.com/documentation/enterprise/re ...

  7. CSS 三角形与圆形

    1. 概述 1.1 说明 通过边框(border)的宽度与边框圆角(border-radius)来设置所需的三角形与圆形. 1.2 边框 宽高都为0时,边框设置的不同结果也不同,如下: 1.四个边框都 ...

  8. 分布式系统的一致性协议之 2PC 和 3PC

    在分布式系统领域,有一个理论,对于分布式系统的设计影响非常大,那就是 CAP 理论,即对于一个分布式系统而言,它是无法同时满足 Consistency(强一致性).Availability(可用性) ...

  9. spring、springMVC、mybatis配置文件

    一.jdbc.properties 文件: driver=com.mysql.jdbc.Driverurl=jdbc:mysql://192.168.31.xxx:3306/abc?useUnicod ...

  10. Confluence 6 MySQL 创建数据库和数据库用户

    一旦你成功的安装和配置了 MySQL 数据库服务器,你需要为你的 Confluence 创建数据库和数据库用户: 在 MySQL 中以超级用户运行 'mysql' .默认的用户为 'root' 同时密 ...