查看原文
其他

[React启蒙系列] React和Babel的基本使用

2016-09-09 zhangwang 前端圈

岩石教育-张旺投稿

本章将使用React构建一个非常简单的HTML页面,目的在于展示如何在运行时使JSX代码正确转换为浏览器可执行的JavaScript以得到我们想要的结果。

使用react.jsreact-dom.js

react.js文件是创建React元素和组件的核心文件,react-dom.js文件用来把React组件渲染为DOM,此文件依赖于react.js文件,需在其后被引入。

一个包含这两个依赖文件的HTML文件示例如下

<!DOCTYPE html>
<html>  <head>    <script src="https://fb.me/react-15.2.0.js"></script>    <script src="https://fb.me/react-dom-15.2.0.js"></script>  </head>
<body>
</body>
</html>

引入这两个文件后,我们就可以开始创建React元素和React组件了,也可以把组件渲染到

DOM中了,以下是一个完整的示例,示例中我们创建了一个名为HelloMessage的组件,该组件内包含一个React <div>节点,该组件也被渲染进了DOM中,渲染位置在<div id="app"></div>元素内。

<!DOCTYPE html>
<html>    <head>        <script src="https://fb.me/react-15.2.0.js"></script>        <script src="https://fb.me/react-dom-15.2.0.js"></script>    </head>
<body>    <div id="app"></div>    <script>        var HelloMessage = React.createClass({            displayName: 'HelloMessage',            render: function render() {                return React.createElement('div',null,'Hello ',this.props.name);            }        });        ReactDOM.render(React.createElement(HelloMessage,{ name: 'John' }), document.getElementById('app'));
   </script>
</body>
</html>

React的基本使用方法就是这样,不过值得注意的是上述代码中没有使用JSX,代码因而略显复杂,下面我们将讨论如在React中使用JSX。


本节笔记

一个称作react-with-addons.js的文件可以代替react.js使用,它包含了.

不要把HTML的<body>当做React渲染的根元素,记住要渲染在<body>里一个具有id的<div>里,这使得React有自己的独立空间,而不用担心如果其他因素如果需要操作<body>里的子元素会影响React的使用。

使用JSX

上例中的<HelloMessage>组件是中,React使用到了React.createClass()React.createElement()两个方法,这段代码就算可以直接运行在浏览器中。

使用JSX,可以极大的简化React元素的创建,JSX抽象化了React.createElement()函数的使用,其语法风格类似于HTML语法风格。对比如下代码可以让你更好的理解这一点。

// 使用React.createElement()
return React.createElement('div',null,'Hello',this.props.name);
//使用JSX
return <div>Hello {this.props.name}</div>

通过Babel,JSX会把转换为使用React.createElement()类的ES5的语句,以使得其能被现今的浏览器引擎识别。

有了Babel,其实你可以把JSX当做写在JavaScript里的HTML代码。本书后续有一章将单独讲解JSX,那时我们再详细讨论JSX的其它特性。

不过现在我们应该明白,使用React并非必须使用JSX,JSX只是一种直观的创建React nodes的方法,它是对React.createElement()方法的抽象,通过Babel,JSX语句也可以直接在浏览器中运行了。

转换JSX

一般说来,JSX代码一般在开发阶段通过使用Babel命令行工具(Babel CLI)或者类似于webpack这样的打包工具处理。不过我们也可以像使用使用jQuery那样,引用脚本文件在浏览器中处理JSX代码,这是最方便的方法,我们在此先这样做。

不过遗憾的是新版的Babel(Babel6以后)不再提供这种直接引用的文件,因此需要使用老版本的Babel(5.8.23)来在浏览器中处理JSX文件。

使用browser.js(Babel5.8.23)在浏览器中转换JSX

下例还是上面已经见过的那个<HelloMessage>组件,这次我在其中加入了brower.js的引用,用以转换JSX代码,注意引用的<script>的type为type="text/babel".

<!DOCTYPE html>
<html>    <head>        <script src="https://fb.me/react-15.2.0.js"></script>        <script src="https://fb.me/react-dom-15.2.0.js"></script>        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>    </head>
<body>    <div id="app"></div>    <script type="text/babel">        var HelloMessage = React.createClass({            render: function() {
               return <div>Hello {this.props.name}</div>;
           }        });        ReactDOM.render(<HelloMessage name="John" />, document.getElementById('app'));
   </script>
</body>
</html>

在运行时引用babel.js虽然容易使用而且还很方便,不过并不是一种好的方案,因为需要转换,所以更加耗时,这一缺点在产品阶段显得更加明显。类似于JSFiddle这样的工具,在线转换React用的就是这种方法。


本节笔记

Babel是React团队选择的在使用React过程中转换ES*和JSX为ES5语句的工具,可以从了解Babel详细的用法。

使用JSX有以下好处:

1、容易理解和修改,对CSS开发者友好;

2、在JavaScript中使用HTML可以避免使用模板,JSX并非一种模板,它其实是用来描述UI组件树的一种JavaScript语句拓展;

3、使用JSX,使你更容易找到可能出错的地方;

4、JSX促进inline styles的发展,这可能是一件很棒的事情;

5、能让你更加了解JSX;

6JSX被列为了ECMAScript用以拓展类XML语句的,所以放心使用吧。

使用ES6和RS*

Babel并非React的一部分,实际上,Babel的主要用途并非一个JSX语句转换器。Babel主要是一个JavaScript转换器,它可以转换各种ES*代码为浏览器可识别的ES代码。就目前来说,Babel主要会转换ES6和ES7语句为ES5语句,转换JSX看起来倒像是其的一个附加功能。

有了Babel,我们可以放心的在React中使用最新的ES语句了。

以下是使用ES6语句书写的<HelloMessage>组件,不用担心它的兼容性,Babel都帮我们做好了。

<!DOCTYPE html>
<html>    <head>        <script src="https://fb.me/react-15.2.0.js"></script>        <script src="https://fb.me/react-dom-15.2.0.js"></script>        <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>    </head>
<body>    <div id="app"></div>    <script type="text/babel">        class HelloMessage extends React.Component { //notice use of React.Component            render(){
               return <div>Hello {this.props.name}</div>;
           }        };        ReactDOM.render(<HelloMessage name="John" />, document.getElementById('app'));        /*** ES5写法 ***/        /*var HelloMessage = React.createClass({            render: function() {                return <div>Hello {this.props.name}</div>;            }        });        ReactDOM.render(<HelloMessage name="John" />, document.getElementById('app'));*/
   </script>
</body>
</html>

Babel会转换如下代码

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

转换后的结果如下

"use strict";
var _createClass = (function() {
   function defineProperties(target, props) {
           for (var i = 0; i < props.length; i++) {
           var descriptor = props[i];            descriptor.enumerable = descriptor.enumerable || false;            descriptor.configurable = true;
           if ("value" in descriptor) descriptor.writable = true;
           Object.defineProperty(target, descriptor.key, descriptor);        }    }    return function(Constructor, protoProps, staticProps) {
            if (protoProps) defineProperties(Constructor.prototype, protoProps);
            if (staticProps) defineProperties(Constructor, staticProps);
            return Constructor;    }; })();
            
var _get = function get(_x, _x2, _x3) {
   var _again = true;    _function: while (_again) {
       var object = _x,        property = _x2,        receiver = _x3;        _again = false;
       if (object === null) object = Function.prototype;
           var desc = Object.getOwnPropertyDescriptor(object, property);
           if (desc === undefined) {
               var parent = Object.getPrototypeOf(object);
               if (parent === null) {
                   return undefined;            } else {                _x = parent;                _x2 = property;                _x3 = receiver;                _again = true;                desc = parent = undefined;
               continue _function;            }        } else if ("value" in desc) {
           return desc.value;        } else {
           var getter = desc.get;
           if (getter === undefined) {
               return undefined;            }
           return getter.call(receiver);        }    } };
           
function _classCallCheck(instance, Constructor) {
   if (! (instance instanceof Constructor)) {
       throw new TypeError("Cannot call a class as a function");    } }
       
function _inherits(subClass, superClass) {
   if (typeof superClass !== "function" && superClass !== null) {
       throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);    }    subClass.prototype = Object.create(superClass && superClass.prototype, {        constructor: {            value: subClass,            enumerable: false,            writable: true,            configurable: true        }    });
   if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  
var HelloMessage = (function(_React$Component) {    _inherits(HelloMessage, _React$Component);
   function HelloMessage() {        _classCallCheck(this, HelloMessage);        _get(Object.getPrototypeOf(HelloMessage.prototype), "constructor", this).apply(this, arguments);    }    _createClass(HelloMessage, [{        key: "render",        value: function render() {
           return React.createElement(
           "div",
           null,
           "Hello ",
           this.props.name            );        }    }]);
   return HelloMessage; })(React.Component); ;
    ReactDOM.render(React.createElement(HelloMessage, {    name: "John"
}), document.getElementById('app'));

大多数ES6的特性都能被安全的转换(少数会有警报)。

本节笔记

Babel的主要用途是转换新标准的JavaScript代码为浏览器现今兼容的代码,同时它也提供JSX语句的转换;

阅读可获取更多关于Babel的信息。

在JSFiddle中练习使用React

本文谈论到的基本设置在JSFiddle中已经实现,JSFiddle正是引用了react.jsreact-dom.jsbrower.js,这使得我们可以直接在该网站上练习使用React。以下是一个内嵌在网页中的JSFiddle,内容还是我们一直提起的HelloMessage组件,点击Result可以查看渲染结果。

JSFiddle为我们提供一个较好的React学习过程中的场所,多多练习吧,同志们。

【React启蒙系列文章】

一、[React启蒙系列] 初探React

二、[React启蒙系列] 学习React前需要理解的名词


【您可能感兴趣的文章】

一、手把手教你用react

二、React入门及资源指引

三、利用ESLint检查代码质量

四、构建一个安全的 JavaScript 沙箱

五、入门Webpack,看这篇就够了

六、第三届CSS大会广州找场地啦~~求介绍~~

七、Web Components 是个什么样的东西

八、JavaScript 被忽视的细节



前端圈--打造专业的前端技术会议

为web前端开发者提供技术分享和交流的平台

打造一个良好的前端圈生态,推动web标准化的发展

官网:http://fequan.com

微博:fequancom | QQ群:41378087


长按二维码关注我们

投稿:content@fequan.com

赞助合作:apply@fequan.com


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存