React启蒙系列翻译React和Babel的基本使用

React和Babel的基本使用

本章将使用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','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 handbook了解Babel详细的用法。

  • 使用JSX有以下好处

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

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

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

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

  • JSX Gotchas能让你更加了解JSX;

  • JSX被列为了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","Hello ",this.props.name

            );

        }

    }]);

    return HelloMessage;

})(React.Component);

;

ReactDOM.render(React.createElement(HelloMessage,{ name: "John" }),document.getElementById('app'));

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

本节笔记

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

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

在JSFiddle中练习使用React

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

点击JSFiddle查看更多

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

链接

React启蒙译文全书
React&&Babel Basic setup

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom