JSX语法


  • administrators

    什么是JSX

    JSX是React的核心组成部分,它使用XML标记的方式去直接声明界面,界面组件之间可以互相嵌套。
    JSX=JavaScriptXML
    JSX可以理解为在JS中编写与XML类似的语言(与XML有本质上的不同),它的目的不是要在浏览器或者引擎中实现,也不是把其加入ECMAScript标准。它的目的是通过各种编译器将这些标记编译成标准的JS语言。
    JSX是:

    • 列表基于ECMAScript的一种新特性(并不是一种新语言)

    • 列表一种定义带属性树结构(DOM结构)的语法

    JSX不是:

    • 列表XML或者HTML

    • 列表一种限制 (你不需要为了 React 使用 JSX,可以直接使用纯粹的 JS。但更建议使用 JSX , 因为它能定义简洁且我们熟知的包含属性的树状结构语法。)

    JSX的特点:

    • 列表类XML语法容易接受,结构清晰

    • 列表增强JS语义

    • 列表抽象程度高,屏蔽DOM操作,跨平台

    • 列表代码模块化

    • 列表JSX并不是新语言,也没有改变JavaScript的语法,只是对JavaScript的拓展。

    JSX并不是新语言,也没有改变JavaScript的语法,只是对JavaScript的拓展。

    JSX语法

    JSX本身就和XML语法类似,可以定义属性以及子元素。唯一特殊的是可以用大括号来加入JavaScript表达式,例如:

    class HelloMessage extends React.Component {
        render() {
            return <div>Hello {this.props.name}</div>;
        }
    }
    ReactDOM.render(
            <HelloMessage name="worldsong"/>,
        document.getElementById('root')
    ); 
    

    1. 元素名

    自定义出的组件标签名,React 的 JSX 里约定分别使用首字母大、小写来区分本地组件的类和 HTML 标签。render渲染时,会把大写的组件名定义为自定义组件,把小写的组件名定义为HTML自带的标签名进行渲染。
    var HelloMessage =
    JSX的标签与函数名都是使用的驼峰命名。

    • 列表htmlFor和className
      for和class为js的保留字,在书写for与class时需要修改为htmlFor何className,注意都是使用的驼峰命名。

    • 列表自闭合标签
      在 JSX 中, <MyComponent /> 是合法的,而 <MyComponent>就不合法。 所有的标签都必须闭合,可以是自闭和的形式,也可以是常规的闭合。

    • 列表注意:所有 React component 都可以采用自闭和的形式,包括div等

    2. 节点属性

    如果往原生 HTML 元素里传入 HTML 规范里不存在的属性,React 不会显示它们。如果需要使用自定义属性,要加 data- 前缀。
    <div data-custom-attribute="foo" />
    然而任意属性支持自定义元素
    <x-my-component custom-attribute="foo" />
    `

    3. Javascript 表达式

    要使用 JavaScript 表达式作为属性值,只需把这个表达式用一对大括号 ( { } ) 包起来,不要用引号 ( " " )。
    求值表达式本身与JSX没有多大关系,是JS中的特性。它是会返回值的表达式,与语句有本质上的不同,在编写JSX时,在 { } 中不能使用语句(if语句、for语句等等)。我们不能直接使用语句,但可以把语句包裹在函数求值表达式中运用。建议把函数表达式独立出来,在 { } 调用。

    • 列表条件判断的写法
      你没法在JSX中使用 if-else 语句,因为 JSX 只是函数调用和对象创建的语法糖。在 { } 中使用,是不合法的JS代码,不过可以采用三元操作表达式。例如:
    class HelloMessage extends React.Component {
        render() {
            return <div>Hello {this.props.name ? this.props.name : "World"}</div>;
        }
    }
    ReactDOM.render(
            <HelloMessage />,
        document.getElementById('root')
    );
    
    • 可以使用比较运算符“ || ”来书写,如果左边的值为真,则直接返回左边的值,否则返回右边的值,与if的效果相同。
    class HelloMessage extends React.Component {
        render() {
            return <div>Hello {this.props.name || "World"}</div>;}
    }
    ReactDOM.render(
        <HelloMessage />,
        document.getElementById('root')
    );
    
    • 也可以使用变量来书写
    class HelloMessage extends React.Component {
        getName() {
            if (this.props.name)
                return this.props.name
            else
                return "world"
        }
        render() {
            var name = this.getName();
            return <div>Hello {name}</div>;
        }
    }
    
    ReactDOM.render(
        <HelloMessage />,
        document.getElementById('root')
    );
    
    • 列表其中可以把变量去掉,直接在 { } 中调用函数。例如:
    render() {
        return <div>Hello {this.getName()}</div>;
    }
    
    • 函数表达式
      ( )有强制运算的作用。例如:
    class HelloMessage extends React.Component {
        render() {
            return <div>Hello {
                (function (obj) {
                    if (obj.props.name)
                        return obj.props.name
                    else
                        return "World"
                }(this))
            }</div>;
        }
    }
    ReactDOM.render(
        <HelloMessage name={"worldsong"} />,
        document.getElementById('root')
    );
    

    外括号“ )”放在外面和里面都可以执行。唯一的区别是括号执行完毕拿到的是函数的引用,然后再调用;括号放在外面的时候拿到的事返回值。需传入(this)。

    4. 注释

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

    var content = (
      <Nav>
        {/* 一般注释, 用 {} 包围 */}
        <Person
          /* 多
             行
             注释 */
          name={window.isLoggedIn ? window.name : ''} // 行尾注释
        />
      </Nav>
    );
    

    5.样式

    尽管在大部分场景下我们应该将样式写在独立的CSS文件中,但是有时对于某个特定组件而言,其样式相当简单而且独立,那么也可以将其直接定义在JSX中。在JSX中使用样式和真实的样式也很类似,通过style属性来定义,但和真实DOM不同的是,属性值不能是字符串而必须为对象,需要注意的是属性名同样需要驼峰命名法。例如:

    var style = {
        color : "red",
        border : "1px solid #000"
    }
    class HelloMessage extends React.Component {
        render() {
            return <div>Hello {this.props.name}</div>;
        }
    }
    
    ReactDOM.render(
        <div style={style}>
            <HelloMessage name="worldsong"/>
        </div>,
        document.getElementById('root')
    );
    

    JSX 陷阱

    1. style属性

    在React中写行内样式时,要这样写,不能采用引号的书写方式。例如:

    ReactDOM.render(
        <div style={{color:'red'}}>
            xxxxx
        </div>,
        document.getElementById('root')
    );
    

    2. HTML转义

    var content='<strong>content</strong>';
    ReactDOM.render(
        <div>{content}</div>,
        document.getElementById('root')
    );
    

    结果页面直接输出内容了:
    0_1520958122987_react_html转义.png

    React默认会进行HTML的转义,避免XSS攻击,如果要不转义,可以这么写:

    var content='<strong>content</strong>';
    ReactDOM.render(
        <div dangerouslySetInnerHTML={{__html: content}}></div>,
        document.getElementById('root')
    );
    

    页面效果:
    0_1520958331615_react_html不转义.png

    3. 自定义HTML属性

    如果在编写React过程中使用了自定义属性,React不会渲染的。
    如果需要使用自定义属性,要加 data- 前缀。

    4. 布尔值、Null 和 Undefined 被忽略

    false、null、undefined 和 true 都是有效的子代,但它们不会直接被渲染。下面的表达式是等价的:

    <div />
    
    <div></div>
    
    <div>{false}</div>
    
    <div>{null}</div>
    
    <div>{undefined}</div>
    
    <div>{true}</div>
    

    这在根据条件来确定是否渲染React元素时非常有用。以下的JSX只会在showHeader为true时渲染<Header />组件。

    <div>
      {showHeader && <Header />}
      <Content />
    </div>
    

    值得注意的是,JavaScript 中的一些 “falsy” 值(比如数字0),它们依然会被渲染。例如,下面的代码不会像你预期的那样运行,因为当 props.message 为空数组时,它会打印0:

    <div>
      {props.messages.length &&
        <MessageList messages={props.messages} />
      }
    </div>
    

    要解决这个问题,请确保 && 前面的表达式始终为布尔值:

    <div>
      {props.messages.length > 0 &&
        <MessageList messages={props.messages} />
      }
    </div>
    

    相反,如果你想让类似 false、true、null 或 undefined 出现在输出中,你必须先把它转换成字符串 :

    <div>
      My JavaScript variable is {String(myVariable)}.
    </div>
    

Log in to reply
 

Looks like your connection to 新前端社区 was lost, please wait while we try to reconnect.