《后端也要懂一点前端系列》React入门

《后端也要懂一点前端系列》React入门

Posted by 不学无数 on December 7, 2019

在上一篇文章中我们使用了webpack搭建项目并成功运行了起来,但是对于在公司使用而言这点是完全不够的,所以接下来我们就开始学习如何使用React框架来进行开发。本篇文章不会探讨原理,只是从一个新手的角度来介绍如何使用。如果没看我第一篇的可以先看我第一篇搭建项目的文章《后端也要懂一点前端系列》使用webpack搭建项目

React起源

以铜为鉴,可以正衣冠;以人为鉴,可以明得失;以史为鉴,可以知兴替。了解一项技术应该先了解其发展过程,及产生原因。

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

前端框架基本概念

  • 模块化:是从代码的角度来进行分析,把一些可复用的代码,抽离为单个的模块; 便于项目的维护和开发
  • 组件化:是从 UI 角度来进行分析的,把一些可复用的 UI 元素,抽离为单独的组件;便于项目的维护和开发

其实上面说的两个概念在任何语言中其实都会体现,其实换句话就是能公用的就公用,不能公用的就自己写。

React中的核心概念

在任何一个学习React的概念中都会涉及到两个技术,一个是虚拟Dom,一个是Diff算法,这里我也不知道其实现原理,大概简单介绍一下其概念,以及我自己对于这两个概念的理解,如果有误希望能够指出来。

虚拟DOM

在了解虚拟DOM之前我们需要知道什么是DOM?DOM是由浏览器中的JS提供功能,所以我们只能人为的使用 浏览器提供的固定的API来操作DOM对象。这里我们随便打开一个网页可以看到这里的每一个标签没其实都是DOM。那么什么是虚拟DOM呢?并不是由浏览器提供的,而是我们程序员手动模拟实现的,类似于浏览器中的DOM,但是有着本质的区别。

那么为什么会出现虚拟DOM呢?其实我觉得还是为了提高浏览器的渲染性能,在这里给大家举一个例子。下面的form表单是前端经常碰见的,而我们点击相应的列也能对其进行排序。例如我们点击了时间从大到小排序了。这里我们可以看到其实我们只需要修改前两列的顺序就行了,如果每次的更新操作都要重新渲染整个DOM树的话,查找,重新渲染的成本都很高。

人物 时间 地点
刘大瘸子 2019-10-20 北京
马二愣子 2019-10-21 上海
赵三驼子 2019-10-19 广州
吴大棒槌 2019-10-18 深圳
郑老六 2019-10-17 杭州
王大麻子 2019-10-16 武汉

那么React推出的虚拟DOM这个概念就是为了解决这个渲染的问题。那么虚拟DOM的出现就是只修改我们需要修改的数据即可,其他数据不动。

在 React 中,render 执行的结果得到的并不是真正的 DOM 节点,结果仅仅是轻量级的 JavaScript 对象,我们称之为 virtual DOM。

Diff算法

上面我们学习了什么是虚拟Dom,那么React是怎么知道了我们需要新数据和旧数据顺序只是前两行不同呢?换句话说就是怎么找到新旧数据的差别呢?这里就用到了Diff算法。

提到树,相信大多数同学立刻想到的是二叉树,遍历,最短路径等复杂的数据结构算法。而在 React 中,树的算法其实非常简单,那就是两棵树只会对同一层次的节点进行比较。

React 只会对相同颜色方框内的 DOM 节点进行比较,即同一个父节点下的所有子节点。当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。这样只需要对树进行一次遍历,便能完成整个 DOM 树的比较。

如何使用

上面简单介绍了概念,接下来就到了如何使用的阶段了。在React学习过程供,需要安装两个包。

  • react:这个专门用来创建React组件,组件生命周期等这些东西。
  • react-dom:里面主要封装了和DOM操作相关的包,比如要把组件渲染到页面上。

安装这两个包的命令是cnpm i react react-dom -S

然后在可以在我们的js文件中引入这两个包了

import React from 'react'
import ReactDOM from 'react-dom'

在 React 中,如要要创建 DOM 元素了,只能使用 React 提供的 JS API 来创建。使用方法是React.createElementReact.createElement()方法,用于创建 虚拟DOM 对象,它接收 3个及以上的参数。

  • 参数1: 是个字符串类型的参数,表示要创建的元素类型
  • 参数2: 是一个属性对象,表示 创建的这个元素上,有哪些属性
  • 参数3: 从第三个参数的位置开始,后面可以放好多的虚拟DOM对象,这写参数,表示当前元素的子节点
var myDiv = React.createElement('div', { title: 'this is a div', id: 'mydiv' }, '这是一个div')

我们上面所写的即创建了这样一个div元素。

<div title="this is a div" id="mydiv">这是一个div</div>

创建完元素以后我们想要将其渲染到页面上,该怎么渲染呢?我们在html文件中创建如下元素。

<div id="app"></div>

接下来我们将上面我们创建的div元素渲染到id=app的元素里面,该怎么做呢?

ReactDOM.render(myDiv, document.getElementById('app'))

接下来我们运行项目,就发现已经渲染到我们的页面了。

JSX语法

如果我们每次创建元素都要有上面一套操作的话,React估计也不会发展这么迅速了,React官方提出了一套JSX语法规范,能够让我们在JS文件中,书写类似HTML那样的代码,快速定义虚拟DOM结构。

JSX语法本质还是使用了React.createElement在内部为我们创建了元素。也就是说哪怕是我们写了JSX这样的标签,也并不是直接将我们的HTML标签渲染到页面上,而是先将其转换成React.createElement这样的JS代码,再渲染。

首先我们依然还是需要命令安装一些东西才能使用,我们安装Babel,安装命令为cnpm i babel-loader@8 @babel/core @babel/preset-env @babel/preset-react -D

  • babel-loader:使用 Babel 转换 JavaScript依赖关系的 Webpack 加载器
  • @babel/core:即 babel-core,将 ES6 代码转换为 ES5
  • @babel/preset-env:即 babel-preset-env,根据您要支持的浏览器,决定使用哪些 transformations / plugins 和 polyfills,例如为旧浏览器提供现代浏览器的新特性
  • @babel/preset-react:即 babel-preset-react,针对所有 React 插件的 Babel 预设,例如将 JSX 转换为函数

Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中

然后我们还需要在项目根目录下创建.babelrc文件,并加入如下内容

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

接着在webpack.config.js文件中在module.exports中进行配置如下

module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
}

接下来我们就能够在js文件中快乐的使用html语言了。

var jsxMyDiv = <div>
    这是使用JSX语法创建的div元素
</div>

ReactDOM.render(jsxMyDiv, document.getElementById('app'))

接下来我们查看页面就可以看到我们创建的元素了。

接下来大概介绍一下JSX语法的注意点。

  • 如果要在 JSX 语法内部,书写 JS 代码了,那么,所有的JS代码,必须写到 {} 内部。

      var titleNmae = "这是一个标题"
      var jsxMyDiv = <div>
          <h1 title = {titleNmae}>测试标题</h1>
      </div>
    	
    
  • 当 编译引擎,在编译JSX代码的时候,如果遇到了<那么就把它当作 HTML代码去编译,如果遇到了 {} 就把 花括号内部的代码当作 普通JS代码去编译;
  • 在{}内部,可以写任何符合JS规范的代码;
  • 在JSX中,如果要为元素添加class属性了,那么,必须写成className,因为 class在ES6中是一个关键字;和class类似,label标签的 for 属性需要替换为 htmlFor.
  • 在JSX创建DOM的时候,所有的节点,必须有唯一的根元素进行包裹;
  • 如果要写注释了,注释必须放到 {} 内部(Contrl+/即可生成注释)

总结

到目前为止从如何创建项目到如何在项目中简单使用React框架,感觉又像当时第一次学习Java一样,什么东西对于我来说都是新的,搭建环境各种出错。但是当最后看到页面上成功显示出想要的东西的时候,瞬间就感觉什么都值了。这或许就是学习的乐趣所在吧。

有感兴趣的可以关注一下我新建的公众号,搜索[程序猿的百宝袋]。或者直接扫下面的码也行。

本文代码地址

参考