您的位置:首页 > Web前端 > JavaScript

深入理解JSX

2016-02-22 11:39 585 查看
一、为什么使用JSX
1、JSX看起来像是XML的JavaScript语法扩展。React可以用来做简单的JSX语法转换。
不需要为了React使用JSX可以使用JS创建,但建议使用JSX,因为可以使定义简洁且我们素质的包含属性的树状结构语法。XML有固定的标签开启和闭合,这能让复杂的树更易于阅读,优于方法调用和队形字面量的形式。
二、JSX使用
1、HTML标签与React组件对比
React可以渲染HTML标签(strings)或者React组件(classes)。
要渲染HTML标签:只需在JSX里使用小写字母开头的标签名。例如:
var myDivElement= <div className="foo"/>;
React.render(myDivElement,document.body);
要渲染React组件只需创建一个大写字母开头的本地变量:
var
MyComponent =
React.createClass({/*...*/});
var
myElement
= <MyComponent someProperty={true}
/>; React.render(myElement,
document.body);

React的JSX里约定分别使用首字母大小写区别本地组件的类和HTML标签。
PS:由于JSX就是JavaScrript,一些标识想是class和for不建议作为XML属性名,作为代替,React
DOM使用className和htmlfor来做对应的属性。

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

PS:JSX总是当作ReactElement执行,具体的实际细节可能不同。

3、JavaScript表达式
属性表达式:
要使用JavaScript表达式作为属性值,只需要把这个表达式用一对大括号包起来,不要用(“”)。例如:
//输入(JSX)
var person =<Person name ={window.isLoggedIn?window.name:''}/>
//输出(JS)
var person =React.createElement(

Person,

{name:window.isLoggedIn?window.name : ''}
};

4、子节点表达式
同样的JavaSCript表达式可用于表述子节点
// 输入 (JSX):

var
content = <Container>{window.isLoggedIn
? <Nav
/> : <Login
/>}</Container>;
// 输出 (JS):

var
content =
React.createElement(
Container,

null,
window.isLoggedIn
?
React.createElement(Nav)
:
React.createElement(Login)
);

注释
JSX里添加注释很容易;他们只是JS表达式而已。你只要在一个标签的子节点内(非最外层)小心地用{}包围要注释的部分。

var content = (
<Nav>
{/*
一般注释,
用 {}
包围 */}
<Person
/*




注释 */
name={window.isLoggedIn ? window.name : ''} //
行尾注释
/>
</Nav>
);

三、JSX的延展属性
1、
var
component = <Component
/>;
component.props.foo
=
x; // 不好
component.props.bar
=
y; // 同样不好
这样是反模式出现错误React不会见长属性类型,有错误就不可以提示,props应该被禁止修改,修改后可能导致预料之外的结果。

2、延展属性(Spread Attributes)
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'

PS: ...这三个点是操作符(也被叫做延展操作符-spread
operator)已经被ES6数组支持。相关的还有ES7规定草案中的Object剩余和延展属性(Rest
and Spread Properties)。

四、JSX的陷阱
1、JSX与HTML很相似但是还是存在一些关键的区别。
首先与DOM的区别,如行内样式style。
React 为了性能和跨浏览器的原因,实现了一个独立于浏览器的事件和 DOM 系统。利用此功能,可以屏蔽掉一些浏览器的 DOM 的粗糙实现。

所有 DOM 的 properties 和 attributes (包括事件处理器)应该都是驼峰命名的,以便和标准的 JavaScript 风格保持一致。我们故意和规范不同,因为规范本身就不一致。然而,data-* 和 aria-* 属性符合规范,应该仅是小写的。

style 属性接收一个带有驼峰命名风格的 JavaScript 对象,而不是一个 CSS 字符串。这与 DOM 中的 style 的
JavaScript 属性保持一致,更加有效,并且弥补了 XSS 安全漏洞。

所有的事件对象和 W3C 规范保持一致,并且所有的事件(包括提交事件)冒泡都正确地遵循 W3C 规范。参考事件系统获取更多详细信息。

onChange 事件表现得和你想要的一样:当表单字段改变了,该事件就被触发,而不是等到失去焦点的时候。我们故意和现有的浏览器表现得不一致,是因为 onChange 是它的行为的一个错误称呼,并且
React 依赖于此事件来实时地响应用户输入。参考表单获取更多详细信息。

表单输入属性,例如 value 和 checked,以及 textarea。这里有更多相关信息

2、HTML实体

可以插入到JSX的文本中。如果JSx表达表达式中显示HTML实体,可以回遇到二次转义的问题。因为React默认会转义所有字符串,为了防止各种XSS攻击。
当:<div>First
· Second</div>时候会:
// 错误: 会显示 “First · Second”

<div>{'First
· Second'}</div>
有多种绕过的方法。最简单的是直接用 Unicode 字符。这时要确保文件是 UTF-8 编码且网页也指定为 UTF-8 编码。
<div>{'First
· Second'}</div>
安全的做法是先找到 实体的 Unicode 编号 ,然后在 JavaScript 字符串里使用:
<div>{'First
\u00b7 Second'}</div>
<div>{'First
' + String.fromCharCode(183)
+ ' Second'}</div>

可以在数组里混合使用字符串和 JSX 元素:
<div>{['First
', <span>·</span>,
' Second']}</div>

万万不得已时候使用原始的HTML。

3、自定义HTML属性
如果向原生HTML元素里传入HTML规范里不存在的属性,React不会显示它们。如果需要使用自定义属性,要加data-前缀

<div data-custom-attribute="foo"
/>

以 aria- 开头的 [网络无障碍] 属性可以正常使用。
<div aria-hidden={true}
/>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: