Heim  >  Artikel  >  Web-Frontend  >  React学习笔记(二)理解JSX_html/css_WEB-ITnose

React学习笔记(二)理解JSX_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-21 08:46:071274Durchsuche

摘要

JSX(JavaScriptXML)提供了一种在JavaScript中编写声明式的XML的方法,使用JSX可以提高组件的可读性,React允许做简单的JSX语法转化。

简介

JSX像是在JavaScript代码里直接写XML的语法,每一个XML标签都会被JSX转换工具转换成纯JavaScript代码,React 官方推荐使用JSX,这个看个人习惯, 如果你喜欢纯JavaScript代码也是可以的,只是使用JSX会给我们带来如下好处:

  • 是原生的JavaScript;
  • 程序结构更容易被直观化;
  • 提供更加语义化且易懂的标签;
  • 抽象了React Element的创建过程;
  • 允许使用熟悉的语法来定义HTML元素树;
  • 可以随时掌控HTML标签以及生成这些标签的代码;

定义第一个组件

简单的理解组件就是对数据和方法的简单封装,目的就是模块化功能。在React当中组件是用来分离关注点的,而不是被当做模板或处理显示逻辑的,在使用React开发应用过程中,往往HTML标签以及生成这些标签的代码之间存在着内在的紧密联系,其实这一坨代码就可以理解为是一个组件。

接下来看一个简单的DEMO,定义我们的第一个组件,按照以往的游戏规则,我们就给他起一个文雅又响亮的名字——“HelloWorld”(React的安装包可以到官网去下载):

<!DOCTYPE html><html>     <head>         <title>Hello React</title>         <!--React核心库-->        <script src="build/react.js"></script>         <!--react-dom.js提供与DOM相关功能-->        <script src="build/react-dom.js"></script>         <!--browser.js将 JSX 语法转为 JavaScript 语法-->        <script src="build/browser.min.js">/script>    </head>     <body>         <HelloWorld>Hello World!</HelloWorld>        <!--为了把 JSX 转成标准的 JavaScript,我们用 `<script type="text/babel">` 标签,然后通过Babel转换成在浏览器中真正执行的内容-->        <script type="text/babel">            // 定义组件HelloWorld           var HelloWorld = React.createClass({                render : function(){                    return (                        <div>                            <h1>this.props.children</h1>                        </div>                    );                }            })        </script>     </body></html>

关于上例中的几点说明

  • React中组件名必须以大写字母开头;
  • React中的组件只能包含一个顶层标签,否则会报错;
  • JSX将两个花括号之间的内容{...}渲染为动态值,花括号指明了一个JavaScript上下文环境,它会将其中内容进行求值,然后渲染为标签中的若干节点;
  • this.props.children是组件的特殊属性,保存了开始标签与结束标签之间的所有子节点,上例中this.props.children = ["Hello World!"];

上述代码如果不使用JSX语法,写法如下:

...// 定义组件HelloWorldvar HelloWorld = React.createClass({displayName:"HelloWorld ",    render : function(){        return (             React.createElement("div",null);             React.createElement("h2",null,this.props.children);           );    }})...

不管使不使用JSX,HelloWorld组件最终的页面渲染结果都是一样的,如下所示:

<div>    <h1>Hello World!</h1></div>

JSX与HTML有何不同

“这个规范(JSX)并不尝试去遵循任何XML或HTML规范。JSX是作为一种ECMAScript特性来设计的,至于大家觉得JSX像XML这一事实,那仅仅是因为大家比较熟悉XML。”——以上内容摘自http://facebook.github.io/jsx/

由此我们可以看出JSX仅仅是像HTML而已,接下来看下他们之间的关键区别。

属性

在HTML中我们往往通过内联的方式设置标签的属性,JSX在支持这种方式的基础上,还支持动态的设置标签的属性,具体实现形式如同我们上个DEMO中的{...},我们可以将属性值定义为JS变量或者是函数。如下所示:

<!--在HTML中标签属性示例--><div id="demo" class="myStyle"></div><!--在JSX中标签属性示例-->var demoId = this.props.id;var demoClass = "myStyle";function getName(){    ...}<div id={demoId} name={this.getName()} className={demoClass}></div>

在React渲染组件的过程中,我们上面定义的变量和函数会被求值,最终生成的DOM结构会反映出这个新的状态。

非DOM属性

下列属性只在JSX中存在:

  • key:可选的唯一标示符,用来唯一的标识一个组件;
  • ref :允许父组件在render之外保持对子组件的一个引用;
  • dangerouslySetInnerHtml:提供插入纯 HTML 字符串的功能,主要为了能和生成 DOM 字符串的库整合。

接下来详细看一下这几个特殊属性的作用。

键(key)在程序运行过程中,由于用户与应用间的交互等原因,一个组件在组件树中的位置很有可能发生改变,最常见的例子就是某列表记录的增、删操作。当然这种情形下组件可能并不需要被销毁并重新创建。

通过给组件设置一个唯一的标识,且保证它在一个渲染周期中保持一致,这样React就能智能的决定该重用哪一个组件,或者销毁并重新创建一个组件,避免不必要的重新渲染,得到性能的提升。

引用(ref)在JSX中可以通过在属性中设置期望的引用名来定义一个引用。

var App = React.createClass({     getInitialState: function() {         return {userInput: ''};     },     handleChange: function(e) {         this.setState({userInput: e.target.value});     },     clearAndFocusInput: function() {         // 清空输入框        this.setState({userInput: ''},         function() {             // 这段代码会在组件重新渲染后执行,使输入框重获焦点            this.refs.theInput.getDOMNode().focus();         });     },     render: function() {     return (         <div>            <div onClick={this.clearAndFocusInput}>                点我!点我!!点我!!!          </div>           <input ref="theInput" value={this.state.userInput} onChange={this.handleChange} />         </div>         );      } });

然后我们就可以在组件中的任何地方使用这个引用了。通过引用获取到的这个对象叫做支持实例。他并不是一个真的DOM,而是React在需要时创建的一个描述对象。你可以通过this.refs.theInput.getDomNode()来访问真实的DOM节点。

设置原始的HTMLdangerouslySetInnerHTML—— 顾名思义,从属性名当中就能看出来,以此来警告它的值( 一个对象而不是字符串 )应该被用来表明净化后的数据。在彻底的理解安全问题后果并正确地净化数据之后,生成只包含唯一 key __html 的对象,并且对象的值是净化后的数据,示例如下:

function createMarkup() {      return {__html: 'First &middot; Second'}; };<div dangerouslySetInnerHTML={createMarkup()} />

这么做的意义在于,当你不是有意地使用

时候,它并不会被渲染,因为 getUsername() 返回的格式是 字符串 而不是一个{__html: ''} 对象。{__html:...} 背后的目的是表明它会被当成 "type/taint" 类型处理。 这种包裹对象,可以通过方法调用返回净化后的数据,随后这种标记过的数据可以被传递给dangerouslySetInnerHTML。 基于这种原因,我们不推荐写这种形式的代码:

这个功能主要被用来与 DOM 字符串操作类库一起使用,所以提供的 HTML 必须要格式清晰(例如:传递 XML 校验 )

注释

由于JSX本质上就是JavaScript,因此也支持JavaScript的注释方式,在JSX中可以用以下两种方式添加注释:

  • 当做一个元素的子节点;
  • 内联在元素的属性中;

示例如下:

// 作为一个元素的子节点<div>{/*多行注释*/}<h1>This is a h1 tag.</h1></div>// 内联在元素的属性中<div><h1/* * 多行注释 */ > 多行注释  </h1></div><div><h1//单行注释 >单行注释</h1></div>

特殊属性

由于JSX会转化为JavaScript函数,所以有些关键词我们不可以使用,比如for和class。

这两个属性分别可以用htmlFor和className替换,参考如下示例:

<label htmlFor="name" ...><input calssName={classes} ...>

样式

React把所有的内联样式都规范化为驼峰形式,同样类似于JavaScript中DOM的style属性,要给组件添加自定义属性,如下:

var styles = {    width:100px;    height:100px;}React.renderComponent({<div style={styles}>...</div>,node})

参考

【1】《React引领未来的用户界面开发框架》【2】 React中文官网

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn