React Native移动开发实战
上QQ阅读APP看书,第一时间看更新

3.3 React JSX

React使用JSX来替代常规的JavaScript,然后通过工具(如Babel)将JSX代码编译成React支持的JS文件,使用JSX可以让代码可读性更高、语义更清晰。React主要由ReactJS和React Native构成,ReactJS是Facebook开源的一个前端框架,React Native是ReactJS原生开发的体现。

3.3.1 JSX入门

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

React的核心机制就包括虚拟DOM,使用JSX语法可以很方便地创建虚拟DOM。例如:

        var root =(
          <ul className="list">
            <li>Content of node1</li>
            <li>Content of node2</li>
          </ul>
       );

上面的代码等价于下面的JavaScript代码:

        var node1 = React.createElement('li', null, 'Content of node1');
        var node2 = React.createElement('li', null, 'Content of node2');
        var rootNode = React.createElement('ul', { className: 'myList' }, node1, node2);

因为使用JSX可以让代码可读性更高、语义更清晰,并且JSX利用虚拟DOM技术减少对实际DOM的操作从而提升了性能。所以,使用JSX进行前端页面开发成为了行业标准之一。

3.3.2 JSX语法

在前端框架中,React的开发思想是基于组件来开发产品,它将一个组件视为一个完全独立的、没有任何其他依赖的模块文件。React发明了JSX,利用特殊的语法格式来创建虚拟DOM,而利用虚拟DOM可以减少对实际DOM的操作,从而提升性能。

JSX语法和XML语法类似,可以定义属性以及子元素,唯一的区别是,JSX用大括号来加入JavaScript表达式。JSX必须借助ReactJS环境才能运行下面介绍JSX中常见的一些语法。

载入方式

目前,加载JSX文件主要有两种方式:内联方式载入和外联方式载入。内联方式载入的相关示例如下:

        <script type="text/babel">
          ReactDOM.render(
            <h1>hello hangge.com</h1>,
            document.getElementById('example')
         );
        </script>

外联方式,是将JSX代码单独放在一个.JSX文件中,然后再使用的文件中引入即可。外联方式载入的示例如下:

        ReactDOM.render(
          <h1>hello hangge.com</h1>,
          document.getElementById('example')
       );

然后,在其他文件引入之前定义的JSX文件,相关示例代码如下:

        <script type="text/babel" src="hello.JSX"></script>

JSX标签,其实就是HTML标签。例如:

        <h1>Hello JSX</h1>

在JavaScript中书写这些标签时,不再需要使用引号将字符串引用起来,而是像直接书写xml文件一样即可。然而还有一类标签是HTML标签所没有的,就是ReactJS创建的组件类标签。ReactJS创建的组件类标签其首字母必须大写。例如,创建一个自定义标签:

        class Hello extends React.Component {
            render(){
                return(
                      <div> hello </div>
               );
            }
        }

三目表达式示例如下:

        var person = <Person name={isLogged ? name : ''} />;

· 数组递归:对数组进行循环,返回每个元素的React组件。例如:

        var lis = this.todoList.todos.map(function(todo){
          return (
            <li>
                <input type="checkbox" checked={todo.done}>
                <span className={'done-' + todo.done}>{todo.text}</span>
            </li>
         );
        });
        var ul =(
          <ul className="unstyled">
            {lis}
          </ul>
       );

· 事件绑定:JSX可以给元素直接绑定事件,如点击事件。React并不会真正绑定事件到每一个具体的元素上,而是采用事件代理的方式,在根节点document上为每种事件添加唯一的事件监听者(Listener),然后通过事件的目标函数(target)找到真实的触发元素的相关事件。例如,

        <button onClick={this.checkAndSubmit.bind(this)}>Submit</button>

· 属性:在JSX中可以通过标签的属性来改变当前元素的样式。例如:

        var property = <h1 width="10px">Hello, React Native</h1>;

在JSX中,我们可以自定义属性,但是自定义属性必须以“data-”开头,这样才能渲染到界面上。例如:

        var hello = <h1 data-test="test" test="test"> Hello React Native</h1>
        React.render(
        hello,
        …
       );

如上所示,data-test标签能够被渲染到页面上,而test标签却不能。

· 样式:在前端Web开发中,我们会将样式文件写在独立的CSS文件中。在JSX中,如果功能相对单一,我们还可以将样式直接写在JSX中。例如:

        <h1 style={{color: '#ff0000', fontSize: '15px'}}>Hello React Native</h1>

· 自定义组件:在JSX中,我们可以使用React自带的一些组件,也可以自定义组件。组件定义之后,可以利用XML语法去声明,而能够使用的XML Tag就是当前JavaScript上下文的变量名,该变量名即为组件名称。例如:

        class HelloWorld extends React.Component{
          render(){
            return(
              <p>
                Hello, <input type="text" placeholder="Your name here" />!
                It is {this.props.date.toTimeString()}
              </p>
           );
          }
        };

        setInterval(function(){
          React.render(
            <HelloWorld date={new Date()} />,
            document.getElementById('example')
         );
        }, 500);

上面声明了一个名为HelloWorld的组件,当需要使用的时候,先导入组件,然后直接在xml中直接使用即可。代码如下:

        var MyHelloWorld = HelloWorld;
        React.render(<MyHelloWorld />, );

当然也可以自定义命名空间,然后使用命名空间的方式引入。例如:

        var sampleNameSpace = {
          MyHelloWorld: HelloWorld
        };
        React.render(<sampleNameSpace.MyHelloWorld />, );