美文网首页
React系列(一)——React的入门和组件化思想

React系列(一)——React的入门和组件化思想

作者: moutory | 来源:发表于2021-05-18 23:38 被阅读0次

前言

React是现在前端使用频率最高的三大框架之一,React率先提出虚拟DOM的思想和实现,使其保持有良好的性能。同时,掌握React语法不仅可以写Web应用的页面,还可以写IOS和安卓的页面,可以说是实用性很强的框架了。本篇文章将对React的入门使用进行讲解,同时针对组件化的思想进行概述,为接下来组件化开发的文章进行知识储备。

一、什么是React

用官网的话一语概括就是,React是用于构建用户页面的JavaScript库。

image.png
在前端页面开发过程中,一共需要经历3个步骤:(1)发送请求接收数据(2)对后台返回的数据进行处理(3)操作DOM呈现页面。而React主要就是专注于第三个步骤来进行优化的。
同时,我们也可以看到React本质上也是一个JS的函数库,我们不妨会想,关于JavaScript的函数库,我们已经知道了有JQuery。那么为什么还需要学React呢?
这里不得不提到传统前端开发存在的三个问题:

1.原生JavaScript操作DOM繁琐、效率低( DOM-API操作UI ) 。(比如document.getElementById()
2.使用JavaScript直接操作DOM,浏览器会进行大量的重绘重排。每次页面上重新请求数据,都会重新刷新当前的相关DOM元素,而原先的DOM节点无法复用。
3.原生JavaScript没有组件化编码方案,代码复用率低。虽然JS中有着模块化的思想,但是只是对JS文件根据模块进行了划分,封装程度还不够,对于css、html重复的代码并没有能够有效的进行提取和封装。

基于上述提到的三个问题,React的出现也自然提供了解决方案。我们可以来看一下React都具备哪些特性:
1.采用组件化模式、声明式编码,提高开发效率及组件复用率。
2.在React Native中可以使用React语法进行移动端开发。
3.使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互。

二、React的快速入门

步骤一:在页面中引入对应的核心依赖包,
    <!-- 引入babel.js依赖,用于将JSX语法代码转换为JS代码 -->
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <!-- 引入 react 基础核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入 react-dom 扩展库 -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>

三个核心依赖包的功能分别如下:

  1. react.js:React核心库。
  2. react-dom.js:提供操作DOM的react扩展库。
  3. babel.min.js:解析JSX语法代码转为JS代码的库。

需要注意的是,三个依赖包的加载顺序有一定的要求,由于react-dom.js文件依赖了react.js文件,所以前者需要放在后者之后才能正常的加载。

步骤二:在页面中定义一个<div>标签,同时定义类型为text/babel<script>标签块
<script type="text/babel">
    
    </script>

需要注意的是,type类型为text/babel表示标签内写的不再是JS,而是JSX语法的代码,而babel会充当转换器的角色,帮助我们把JSX语法的代码转换成JS。(这里稍微解释一下,JSX本质上就是JS,只是对其做了一些封装,多了一些语法规则而已,其目的是为了简化我们的JS开发)

步骤三:在创建的script标签中创建虚拟DOM对象,并将其渲染到页面上
    <script type="text/babel">
        // 创建一个虚拟DOM
        const VDOM = <h1>hello,react</h1>
        // 将虚拟DOM渲染到页面上
        ReactDOM.render(VDOM,document.getElementById('test'));
    </script>

我们可以看到,对于虚拟DOM对象,我们可以直接在上面写标签。而后调用ReactDOM对象的render方法将虚拟DOM对象渲染到页面上。此时,我们可以在页面上看到对应的效果:

快速入门结果图

三、创建虚拟DOM的两种方式

(一)使用JSX方式创建虚拟DOM

我们在上一节中讲到,虚拟DOM的创建可以直接在类型为babelscript标签中以JSX语法的代码直接书写。这种方式使用的前提是导入了我们之前提到的babel.min.js函数库,写法较为简单。

<script type="text/babel">
    const VDOM = <h1  id="test2">Hello,React</h1>
    ReactDOM.render(VDOM,document.getElementById('test'));
 </script>

那我们是不是只能用JSX这种语法来创建虚拟DOM呢?或者说,JSX本质上还是JS,那我能不能用JS来创建虚拟DOM对象呢?答案当然是可以。

(二)使用JS方式创建虚拟DOM

我们可以看到,React也提供了对应的API给我们去创建虚拟DOM对象,需要注意的是,此时我们script标签中使用的类型就是我们熟悉的text/javascript

    <script type="text/javascript">
        //  使用JS创建虚拟DOM
        const VDOM = React.createElement('h1',{id:'test2'},'Hello,React'));
        ReactDOM.render(VDOM,document.getElementById('test'));
    </script>
为什么要使用JSX?

或许有人会有疑问?既然原生的JS也可以创建虚拟DOM对象,那么我们为什么还要学习JSX语法呢?直接使用更加熟悉的JS不是更香?
这种疑问自然是很合理的,原生的JS固然可以满足我们的简单需要,但实际上当场景一旦变得复杂,JSX的优势就体现了出来,我们不妨看下面这个例子:
实现在原<div>标签中,加入id属性为test2span标签,在span标签中再嵌套一个<h1>标签,文本内容为Hello,React。

使用JS实现代码如下:
    <script type="text/javascript">
        //  使用JS创建虚拟DOM
        const VDOM = React.createElement('span',{id:'test2'},React.createElement('h1',{},'Hello,React'));
        ReactDOM.render(VDOM,document.getElementById('test'));
    </script>

为了实现嵌套元素的效果,我们这里需要再次调用React.createElement作为child元素进行传入。

而使用JSX实现的代码如下:
    <script type="text/babel">
        const VDOM = (
            <span id="test2">
                <h1>Hello,React</h1>
            </span>
        )
        ReactDOM.render(VDOM,document.getElementById('test'));
    </script>

我们可以看到,使用JSX可以很清晰地将我们想要的虚拟DOM对象进行定义,虽然最终实现的效果和JS的一致(本质上是经过babel转换后,我们的JSX语句也会被转换成对应的JS语句),但可读性却要高很多,更加便于开发。可以想象一下,当我们要创建的虚拟DOM对象结构非常复杂时,用原生的JS代码进行开发是多么让人头疼的一件事情。

四、虚拟DOM和真实DOM节点的区别

<body>
    <div id="test"></div>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/babel">
        const VDOM = (
            <h1>hi,React</h1>
        )
        var dom = document.getElementById('test');
        console.log('真实dom对象',dom)
        console.log('虚拟DOM对象',VDOM);
        debugger;
        // 由于console并不能真正看到真实的DOM对象,所以需要借助 Dubgger
        // 在debugger 窗口中我们可以看到,相对于虚拟DOM而言,真实的DOM对象会比较“重”(属性比较多和复杂)
        ReactDOM.render(VDOM,document.getElementById('test'));
    </script>
</body>

我们在浏览器中打开这个页面,同时打开控制台观察对应的对象


真实DOM对象
虚拟DOM对象

我们可以从截图中看到,相比于真实的DOM对象,React的虚拟DOM对象属性要简单得多,所以使用起来的代价也比较小。一般来说,我们也会认为虚拟DOM对象是要比真实的DOM对象要“轻”

五、JSX的语法规则

(1)构建虚拟DOM的时候,不要使用单/双引号(下面是错误示范)
    <script type="text/babel">
        const VDOM = (
            '<h1 id="test2">Hello,React~</h1>'
        )
        ReactDOM.render(VDOM, document.getElementById('test'));
    </script>
使用引号会导致JSX代码无法被解析
(2)标签中混入JS表达式时要用{}
    <script type="text/babel">
        const idAttr = 'test2';
        const text = 'Hello,React~';
        const VDOM = (
            <h1 id={idAttr}>
                <span>{text}</span>
            </h1>
        )
        ReactDOM.render(VDOM, document.getElementById('test'));
    </script>
(3)样式的类名指定不要用class,要用className
<head>
 ...
    <style>
        .myClass {
            background-color: yellow;
            width: 200px
        }
    </style>
</head>

<body>

    <div id="test"></div>
...
    <script type="text/babel">
        const idAttr = 'test2';
        const text = 'Hello,React~';
        const VDOM = (
            <h1 id={idAttr} className="myClass">
                <span>{text}</span>
            </h1>
        )
        ReactDOM.render(VDOM, document.getElementById('test'));
    </script>
</body>
(4)内联样式,需要用{{key: 'value',...}}的格式去书写
    <script type="text/babel">
        const idAttr = 'test2';
        const text = 'Hello,React~';
        const VDOM = (
            <h1 id={idAttr} className="myClass">
                <span style={{color:'white',fontSize: '30px'}}>{text}</span>
            </h1>
        )
        ReactDOM.render(VDOM, document.getElementById('test'));
    </script>

需要注意的是,这里用了两对花括号,最外面的花括号意思是里面将使用JS表达式,而里面的花括号表达这是一个JS对象。同时如果style属性不是一个单词的话,需要用类似fontSize这种小驼峰式命名才能生效。

(5)虚拟对象只有一个根标签
    <script type="text/babel">
        const idAttr = 'test2';
        const text = 'Hello,React~';
        const VDOM = (
            <div>
                <h1 id={idAttr} className="myClass">
                    <span style={{ color: 'white', fontSize: '30px' }}>{text}</span>
                </h1>
                <h1 id={idAttr} className="myClass">
                    <span style={{ color: 'white', fontSize: '30px' }}>{text}</span>
                </h1>
            </div>
        )
        ReactDOM.render(VDOM, document.getElementById('test'));
    </script>
(6)标签必须闭合(这点比较简单,就不再举例了)
(7)标签首字母
  • 若首字母为小写时,则将该标签转为html同名元素,如果找不到,则报错
  • 若首字母为大写时,react就会去渲染对应的组件,如果组件没有定义,就会报错

我们这里定义一个good标签,然后查看一下结果

    <script type="text/babel">
        const idAttr = 'test2';
        const text = 'Hello,React~';
        const VDOM = (
                <good>abc</good>
        )
        ReactDOM.render(VDOM, document.getElementById('test'));

    </script>
image.png

我们可以看到,虽然abc值正常显示了出来,但控制台实际上还是报了错,因为由于此时标签的首字母小写,所以会去找html的同名标签,good这种自动以标签自然是不存在的,所以也就报了错。

我们这里定义一个Good标签,然后查看一下结果

使用Good标签结果
我们可以看到,此时的控制台会直接报错说找不到这个名称的组件。

六、模块与组件理解

组件(化)是React框架中十分重要的知识点,谈组件之前,我们先来聊聊什么是模块?

模块其实我们在开发很多语言的时候都有接触到这个概念,比如Java,我们会将一些重复性的代码进行抽取,封装成一个或者一组相关的类,再根据实际的业务对外提供服务。JS中的模块也是如此:向外提供特定功能的js程序, 一般就是一个js文件

那什么是组件呢?

组件可以看成是资源的进一步封装,和后台的代码不同,前端的资源除了js之外还有html、css和各种图片资源等,模块化只能让我们的js实现复用,但对于其他资源来说并不行。所以组件就是用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)。
在企业级开发中,组件的应用可以使得我们资源的可重用性得到提升,减少我们的开发成本,也是前端不断发展下的产物。

相关文章

网友评论

      本文标题:React系列(一)——React的入门和组件化思想

      本文链接:https://www.haomeiwen.com/subject/fvwyjltx.html