首先,严格定义上来讲,JSX 是 react 提供的一种标签式的组件声明语法。JSX 只是一种js语言的扩展语法糖,在正式环境运行前,须要通过 babel 工具编译为正式的 JS 代码。javascript
在正式介绍JSX 以前,咱们有必要理解,react 框架实现了 virtual dom 功能,开发者可经过react的双向绑定、组件、组件嵌套等工具,将页面的构建逻辑交付于react框架便可,而无需执行实际的 DOM 操做。为了实现 virtual dom ,react 将 DOM 映射为 Component 对象,将 DOM 树映射为组件树。为此,react提供了 createClass
接口用于定于 Component;提供了 createElement
接口用于构建组件树。html
JSX 高度兼容HTML,即便是react新手也能够迅速写出 JSX 代码:vue
const element = <div> <button>这是一个 button</button> <button style={{ width: 100 }}>这是一个包含 style 属性的 button</button> <button className="btn btn-default">这是一个带 className 的 button</button> <button className="btn btn-default" onClick={() => alert('click me')}>这是一个带事件处理的 button</button> <div className="btn-group"> <button className="btn btn-default">这是被 div 包围的 button</button> <button className="btn btn-default">这也是被 div 包围的 button</button> </div> </div>;
这是JSX的基本形式,编译后的代码:java
var element = _react2.default.createElement( 'div', null, _react2.default.createElement( 'button', null, '\u8FD9\u662F\u4E00\u4E2A button' ), _react2.default.createElement( 'button', { style: { width: 100 } }, '\u8FD9\u662F\u4E00\u4E2A\u5305\u542B style \u5C5E\u6027\u7684 button' ), _react2.default.createElement( 'button', { className: 'btn btn-default' }, '\u8FD9\u662F\u4E00\u4E2A\u5E26 className \u7684 button' ), _react2.default.createElement( 'button', { className: 'btn btn-default', onClick: function onClick() { return alert('click me'); } }, '\u8FD9\u662F\u4E00\u4E2A\u5E26\u4E8B\u4EF6\u5904\u7406\u7684 button' ), _react2.default.createElement( 'div', { className: 'btn-group' }, _react2.default.createElement( 'button', { className: 'btn btn-default' }, '\u8FD9\u662F\u88AB div \u5305\u56F4\u7684 button' ), _react2.default.createElement( 'button', { className: 'btn btn-default' }, '\u8FD9\u4E5F\u662F\u88AB div \u5305\u56F4\u7684 button' ) ) );
与html主要的不一样点为:react
不能使用 class
声明元素类,改用 className
web
绑定事件必须使用 驼峰命名babel
style 属性必须为对象框架
JSX中,父组件可经过属性方式,将配置值传递到子组件中:dom
const element = <div tabIndex="0" name="someDiv"></div>;
标签属性最终被编译成对象,传递到 createElement
接口,如上述代码编译结果为:ide
var element = React.createElement("div", { tabIndex: "0", name: "someDiv" });
属性值既接受字符串,也接受js表达式,一样经过 {}
闭合,如:
const areWeRocking = true; const element = <div areWeRocking={areWeRocking}></div>;
JSX 中,标签能够包含子标签,子标签集合会被编译为 children
传递到 createElement
函数,如:
const element = <div> <button>这是一个button</button> </div>;
编译结果:
var element = React.createElement( "div", null, React.createElement( "button", null "\u8FD9\u662F\u4E00\u4E2Abutton" ) );
JSX 支持嵌套 js表达式,方式很是简单,使用 {}
包含表达式便可,这使得咱们能够轻易地在JSX实现各类逻辑
循环
const array = [1, 2, 3, 4]; const element = <div>{array.map(item => <span>{item}</span>)}</div>;
分支
const areWeRocking = true; const element = <div>{areWeRocking ? 'awesome' : 'holy shit'}</div>;
函数
const giveMeYourName = () => <strong>tecfan</strong>; const element = <div>{giveMeYourName()}</div>;
JSX 表达能力很是强,一是能够无限制的嵌套组件标签、js代码,实现复杂逻辑;二是支持函数表达式,经过函数咱们能够实现任意功能。
JSX 语法并不晦涩,只有三条简简单单的规则:
经过 XML 形式声明
标签容许声明任意属性
标签内能够嵌套子标签,也能够嵌套js表达式
编译器而言的处理逻辑也会变的很简单:
解析标签名(tagName)
解析标签属性,拼合为属性对象(props)
遍历内容集合(children)
若是内容为JS表达式,执行表达式,并将结果存入 children 变量
若是内容为标签,执行第一步,并将结果存入 children 变量
上面过程当中生成的变量 tagNaem、props、children 被传递到 createElement
接口:
React.createElement( tagName, props, ...children )
在web领域咱们见过太多模板,angular、vue、lodash、swig...各类模板都构造了其独特的语法、控制结构,许多甚至已经大幅度偏离html语法基础。
JSX 则成功的另辟小径,只提供基于html的语法糖,只要熟悉html、js,入门难度很是低。良好的程序结构,应该是简单纯粹,而又不失表达能力的,JSX正符合这种良好设计。