React 的骨架 JSX

2177次阅读  |  发布于5年以前

为什么需要JSX

JSX 是 Facebook 团队提出的一个语法方案,可以在 JavaScript 的代码直接中使用 HTML 标签来编写 JavaScript 对象。其使用的是 XML-like 语法,这种语法方案需要通过 JSXTransformer 来进行编译转换成真实可用的 JavaScript 代码(React 官方已经推荐使用 babel 来代替)。

React 是基于组件的开发思想,React 认为一个组件可以是一个完全独立的没有任何其他依赖的模块文件。一个组件中可以有自己的样式(Inline Style)和结构(JSX编写的HTML)。

在 React 和 JSX 之前,一个组件如果要包含 HTML 结构将面临如下几个问题:

JSX 很好的解决了这些问题。

基本语法

使用 JSX 来创建一个 HTML 标签,首字母小写:

var link = <a href="xxx">Hello World!</a>;

相当于调用了 React.createElement 方法:

var link = React.createElement('a', {href: 'xxx'}, 'Hello World!')

使用 JSX 来创建一个 Component,首字母大写:

var HelloWorld = <HelloWorld foo="bar"></HelloWorld>

首字母的大小写有严格的区分,这样 JSX 可以很简单的通过区分首字母是小写还是大写来判断转换的是 HTML 标签还是自定义的 Component。

JSX 标签的标签都需要有完整的结束符号,否则编译会报错。

<div></div>
    <input type="text" />

变量和逻辑

JSX 中可以通过 {xxx} 来插入一个 JavaScript 变量:

var name = 'xiao ming';
    <a href="xxx">Hello {name}!</a>

没错,HTML 语法就是这样和 JavaScript 语法无缝的结合!

如果要在 JSX 中插入一段 JavaScript 代码,那么一次只能插入一个一次就能执行完的语句。

var link = <a href="xxx">Hello {if (conditions) {'xiao ming'}}!</a>

上面的代码编译后会是这样的:

var link = React.createElement('a', {href: 'xxx'}, if (conditions) {'xiao ming'})

编译后可以看到明显存在语法错误,可以使用三元运算符来将条件判断语句简化成一个语句:

var link = <a href="xxx">Hello {conditions ? 'xiao ming' : ''}!</a>

多行语句和根节点

无论你的 JSX 代码有多长,每一段代码都只能有一个根节点,否则编译通不过,因为 React 需要确保一个组件只能有一个根节点。

// 错误的写法
    var btnBox = (
        <button>Click me</button>
        <p>hello world!</p>
    );

    // 正确的写法
    var btnBox = (
        <div>
            <button>Click me</button>
            <p>hello world!</p>
        </div>
    );

如果想在 JSX 中添加注释,需要使用多行注释的语法并确保其包裹在 {} 中。

<div>
        <h3>title</h3>
        {/*<p>text</p>/*}
    </div>

关键字冲突

因为 JSX 是直接将 HTML 写在 JavaScript 代码中,如果在 HTML 中有的属性中有 JavaScript 的关键字,必须进行转换,转换规则和在 JavaScript 中使用 DOM 的 property 一样。如 class 需转换成 classNamefor 要转换成 htmlFor,还有其他的关键字这里不做一一列举。

false in JSX

false 在 JSX 中,会有不同的作用。

 <div id={false}>
        <input type="text" name="name" value={false} />
        <button type="button" name="button" disabled={false}>hello</button>
        <p>{false}</p>
    </div>

id={false}value={false} 都换转换成字符串 falsedisabled={false} 是设置 disabled 属性为 false<p>{false}</p> 表示该 p 标签没有子元素。

Inline Style

上面提到过 React 希望一个组件中可以是独立的,可以将样式直接通过 JavaScript 的对象插入到 JSX 中,这样就可以给一个组件定义样式了。

var paraStyle = {
        color: '#fff',
        fontSize: '14px'
    };

    var para = (
        <p style={paraStyle}></p>
    );

在定义样式的时候,对象的 key 就是样式的属性,属性中如果有中划线,需将其换成驼峰式,value 就是对应的属性值。对于一些复杂的伪类选择器,以及其他的一些高级的 CSS 特性,有相应的库可以对其支持。

将样式通过内联的形式写在组件内部,虽然有违分离原则,但是其确实解决了因为分离带来的组件独立性的问题,虽然是反模式化的,但确确实实解决了一个痛点。

命名空间

JSX 中还可以支持组件的命名空间,可以让组件的层次更清晰,更语义化。

var Form = React.createClass({ ... });
    Form.Row = React.createClass({ ... });
    Form.Label = React.createClass({ ... });
    Form.Input = React.createClass({ ... });

    var App = (
        <Form>
            <Form.Row>
                <Form.Label />
                <Form.Input />
            </Form.Row>
        </Form>
    );

代码风格建议

为了代码有更好的可读性,无论是单行语句还是多行语句,都建议使用 () 来包裹 JSX 语句。在 JSX 中插入 JavaScript 语句的时候尽量不要嵌套太长的三目运算符,JSX 本身就是为了开发更简便和更好的维护性。如果把 JSX 也写成一坨一坨可读性很差的代码,实在太不应该了。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8