深入理解JSX

来源:互联网 发布:软件著作权抵税 编辑:程序博客网 时间:2024/05/16 06:31

    一、为什么使用JSX

    1JSX看起来像是XMLJavaScript语法扩展。React可以用来做简单的JSX语法转换。

    不需要为了React使用JSX可以使用JS创建,但建议使用JSX,因为可以使定义简洁且我们素质的包含属性的树状结构语法。XML有固定的标签开启和闭合,这能让复杂的树更易于阅读,优于方法调用和队形字面量的形式。

    二、JSX使用

    1HTML标签与React组件对比

    React可以渲染HTML标签(strings)或者React组件(classes)。

    要渲染HTML标签:只需在JSX里使用小写字母开头的标签名。例如:

    var myDivElement= <div className="foo"/>;

    React.render(myDivElement,document.body);

    要渲染React组件只需创建一个大写字母开头的本地变量:

    varMyComponent =React.createClass({/*...*/});

     varmyElement= <MyComponent someProperty={true}/>; React.render(myElement,document.body);

     

    ReactJSX里约定分别使用首字母大小写区别本地组件的类和HTML标签。

    PS:由于JSX就是JavaScrript,一些标识想是classfor不建议作为XML属性名,作为代替,React DOM使用classNamehtmlfor来做对应的属性。

     

    2、转换

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

     

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

     

    3JavaScript表达式

    属性表达式:

    要使用JavaScript表达式作为属性值,只需要把这个表达式用一对大括号包起来,不要用(“”)。例如:

    //输入(JSX

    var person =<Person name ={window.isLoggedIn?window.name:''}/>

    //输出(JS

    var person =React.createElement(

    Person,

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

    };

     

    4、子节点表达式

    同样的JavaSCript表达式可用于表述子节点

    // 输入 (JSX):

    varcontent = <Container>{window.isLoggedIn? <Nav/> : <Login/>}</Container>;

     // 输出 (JS):

    varcontent =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

    varcomponent = <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的陷阱

    1JSXHTML很相似但是还是存在一些关键的区别。

    首先与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这里有更多相关信息

     

    2HTML实体

     

    可以插入到JSX的文本中。如果JSx表达表达式中显示HTML实体,可以回遇到二次转义的问题。因为React默认会转义所有字符串,为了防止各种XSS攻击。

    当:<div>First&middot; Second</div>时候会:

    // 错误: 会显示 “First &middot; Second”

    <div>{'First &middot; 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>&middot;</span>, ' Second']}</div>

     

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

     

    3、自定义HTML属性

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

     

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

     

    以 aria- 开头的 [网络无障碍] 属性可以正常使用。

    <div aria-hidden={true}/>

     


1 0