JSX
是一种javascript
语法扩展(也就是语法糖),相似于XML
,通常用babel
编译成javascript
javascript
React
里可使用原生的javascript
,可是React
官方推荐使用JSX
,使用JSX
,组件的结构和组件之间的关系看上去更加清晰。
前端界面的最基本功能在于展示数据,为此大多数框架都使用了模板引擎
模板能够直观的定义UI来展示Model中的数据,你没必要手动的去拼出一个很长的HTML字符串,几乎每种框架都有本身的模板引擎。传统MVC框架强调界面展现逻辑和业务逻辑的分离,所以为了应对复杂的展现逻辑需求,这些模板引擎几乎都不可避免的须要发展成一门独立的语言,如上面代码所示,每一个框架都有本身的模板语言语法。而这无疑增长了框架的门槛和复杂度。React
直接放弃了模板而发明了JSX
。看上去很像模板语言,但其本质是经过代码来构建界面,这使得咱们再也不须要掌握一门新的语言就能够直观的去定义用户界面:掌握了javascript
就已经掌握了JSX
。JSX
完美利用了javascript
自带的语法和特性,咱们只要记住HTML只是代码建立DOM的一种语法形式,就很容易理解JSX
。而这种使用代码构建界面的方式,彻底消除了业务逻辑和界面元素之间的隔阂,让代码更加直观和易于维护。html
var Nav, Profile; // Input (JSX): var app = <Nav color="blue"><Profile>click</Profile></Nav>; // Output (JS): var app = React.createElement( Nav, {color:"blue"}, React.createElement(Profile, null, "click") );
也就是说,咱们写一个XML标签,实质上就是在调用 React.createElement
这个方法,并返回一个 ReactElement
对象。
扩展: React.createElement
用法前端
ReactElement createElement( string/ReactClass type, [object props], [children ...] )
经过上面的代码能够看出JSX
的优点,XML有着开闭标签,在构建复杂的树形结构时,比函数调用和对象字面量更易读java
React.render
方法能够渲染HTML结构,也能够渲染React组件。
渲染HTML标签,声明变量采用首字母小写segmentfault
var myDivElement = <div className="foo" />; ReactDOM.render(myDivElement, document.getElementById('example'));
渲染React组件,声明变量采用首字母大写数组
var MyComponent = React.createClass({/*...*/}); var myElement = <MyComponent someProperty={true} />; ReactDOM.render(myElement, document.getElementById('example'));
JSX
的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。JSX
容许直接在模板插入 JavaScript 变量。若是这个变量是一个数组,则会展开这个数组的全部成员:安全
var arr = [ <h1>Hello world!</h1>, <h2>React is awesome</h2>, ]; React.render( <div>{arr}</div>, document.getElementById('example') );
// Input (JSX): var person = <Person name={window.isLoggedIn ? window.name : ''} />; // Output (JS): var person = React.createElement( Person, {name: window.isLoggedIn ? window.name : ''} );
// Input (JSX): var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>; // Output (JS): var content = React.createElement( Container, null, window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login) );
// These two are equivalent in JSX for disabling a button <input type="button" disabled />; <input type="button" disabled={true} />; // And these two are equivalent in JSX for not disabling a button <input type="button" />; <input type="button" disabled={false} />;
JSX 里添加注释很容易;它们只是 JS 表达式而已。你只须要在一个标签的子节点内(非最外层)当心地用 {} 包围要注释的部分。babel
var content = ( <Nav> {/* 通常注释, 用 {} 包围 */} <Person /* 多 行 注释 */ name={window.isLoggedIn ? window.name : ''} // 行尾注释 /> </Nav> );
因为JSX只是一种语法,所以JavaScript的关键字class, for等也不能出如今XML中,而要使用className, htmlFor代替,这和原生DOM在JavaScript中的建立也是一致的。网络
若是你事先知道组件须要的所有 Props(属性),JSX 很容易地这样写:app
var component = <Component foo={x} bar={y} />;
若是你不知道要设置哪些 Props,那么如今最好不要设置它:
var component = <Component />; component.props.foo = x; // bad component.props.bar = y; // also bad
这样是反模式,由于 React 不能帮你检查属性类型(propTypes)。这样即便你的 属性类型有错误也不能获得清晰的错误提示。
Props 应该被看成禁止修改的。修改 props 对象可能会致使预料以外的结果,因此最好不要去修改 props 对象。
能够用展开属性来写
var props = {}; props.foo = x; props.bar = y; var component = <Component {...props} />;
传入对象的属性会被复制到组件内。
它能被屡次使用,也能够和其它属性一块儿用。注意顺序很重要,后面的会覆盖掉前面的。
var props = { foo: 'default' }; var component = <Component {...props} foo={'override'} />; console.log(component.props.foo); // 'override'
JSX 与 HTML 很是类似,可是有些关键区别要注意。
在React中写行内样式时,要这样写,不能采用引号的书写方式
React.render( <div style={{color:'red'}}> xxxxx </div>, document.body );
React默认会进行HTML的转义,避免XSS攻击
有多种绕过的方法。最简单的是直接用 Unicode 字符。这时要确保文件是 UTF-8 编码且网页也指定为 UTF-8 编码。
<div>{'First · Second'}</div>
安全的作法是先找到 实体的 Unicode 编号 ,而后在 JavaScript 字符串里使用。
<div>{'First \u00b7 Second'}</div> <div>{'First ' + String.fromCharCode(183) + ' Second'}</div>
还能够直接使用原生的HTML,但能够看出不推荐这种作法
<div dangerouslySetInnerHTML={{'{{'}}__html: 'First · Second'}} />
若是往原生 HTML 元素里传入 HTML 规范里不存在的属性,React 不会显示它们。若是须要使用自定义属性,要加 data- 前缀。
<div data-custom-attribute="foo" />
以 aria- 开头的 [网络无障碍] 属性能够正常使用。
<div aria-hidden={true} />
在JSX中是不能够直接在{}中加入if-else的,可使用下面这种三元表达式:
React.render(<div id={condition ? 'msg' : ''}>Hello World!</div>, mountNode);
在三元运算符知足不了的时候,React建议的方式是在JS代码中使用if表达式
var loginButton; if (loggedIn) { loginButton = <LogoutButton />; } else { loginButton = <LoginButton />; } return ( <nav> <Home /> {loginButton} </nav> );
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> );
ReactDOM.render(<div id={false} />, mountNode);
渲染出 id="false"
ReactDOM.render(<input value={false} />, mountNode);
渲染出字符串"false"做为input的value
ReactDOM.render(<div>{false}</div>, mountNode);
渲染出无子元素
用法以下
命名空间式组件容许你使用一个父组件,而其余的子组件是他的属性
var Form = MyFormComponent; var App = ( <Form> <Form.Row> <Form.Label /> <Form.Input /> </Form.Row> </Form> ); var MyFormComponent = React.createClass({ ... }); MyFormComponent.Row = React.createClass({ ... }); MyFormComponent.Label = React.createClass({ ... }); MyFormComponent.Input = React.createClass({ ... });
注意点以下: React.js的命名空间的组件
只在0.11及以上版本可用