前言

后端没问题,需要用前端框架实现一些页面

安装

环境nodejs就不说了,安装最新的稳定版本就行,直接安装一个脚手架

1
npm install -g create-react-app

通过脚手架生成react项目,后面跟着项目名称,时间有点长,等待完成就行

1
create-react-app my-app

最后会提示我们cd项目名称,在使用npm start命令进去启动项目

image-20220726154842919

我们照做,启动项目,会自动跳到浏览器访问http://localhost:3000/,这是脚手架自带的页面逻辑,我们不需要。

所以,删除掉新项目中 src/ 文件夹下的所有文件。删除后会提示

image-20220726155341401

这个index.js被我们删了,我们重新创建一个,这个是入口的js,既然是入口的js,那需要引入react依赖

1
2
import React from 'react';
import ReactDom from 'react-dom'
  • React:这个是react核心
  • react-dom:这个react进行dom操作的抽象模块

其实,感觉react像是个java,思想就是抽象。把模块抽象出一个一个类,在组装即可。而官方的说明是:

React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。

react基础概念(copy)

1、React的起源和发展

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

2、React与传统MVC的关系

轻量级的视图层A JavaScript library for building user interfaces

React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式;React 构建页面 UI 的库。可以简单地理解为,React 将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,就成了我们的页面。

3、React高性能的体现:虚拟DOM

React高性能的原理:

在Web开发中我们总需要将变化的数据实时反应到UI上,这时就需要对DOM进行操作。而复杂或频繁的DOM操作通常是性能瓶颈产生的原因(如何进行高性能的复杂DOM操作通常是衡量一个前端开发人员技能的重要指标)。

React为此引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。而且React能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A-B, B-A,React会认为A变成B,然后又从B变成A UI不发生任何变化,而如果通过手动控制,这种逻辑通常是极其复杂的。

尽管每一次都需要构造完整的虚拟DOM树,但是因为虚拟DOM是内存数据,性能是极高的,而对实际DOM进行操作的仅仅是Diff分,因而能达到提高性能的目的。这样,在保证性能的同时,开发者将不再需要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只需要关心在任意一个数据状态下,整个界面是如何Render的。

React Fiber:

在react 16之后发布的一种react 核心算法,React Fiber是对核心算法的一次重新实现(官网说法)。之前用的是diff算法。

在之前React中,更新过程是同步的,这可能会导致性能问题。

当React决定要加载或者更新组件树时,会做很多事,比如调用各个组件的生命周期函数,计算和比对Virtual DOM,最后更新DOM树,这整个过程是同步进行的,也就是说只要一个加载或者更新过程开始,中途不会中断。因为JavaScript单线程的特点,如果组件树很大的时候,每个同步任务耗时太长,就会出现卡顿。

React Fiber的方法其实很简单——分片。把一个耗时长的任务分成很多小片,每一个小片的运行时间很短,虽然总时间依然很长,但是在每个小片执行完之后,都给其他任务一个执行的机会,这样唯一的线程就不会被独占,其他任务依然有运行的机会。

4、React的特点和优势

(1) 虚拟DOM

我们以前操作dom的方式是通过document.getElementById()的方式,这样的过程实际上是先去读取html的dom结构,将结构转换成变量,再进行操作。而reactjs定义了一套变量形式的dom模型,一切操作和换算直接在变量中,这样减少了操作真实dom,性能真实相当的高,和主流MVC框架有本质的区别,并不和dom打交道

(2) 组件系统

react最核心的思想是将页面中任何一个区域或者元素都可以看做一个组件 component

那么什么是组件呢?

组件指的就是同时包含了html、css、js、image元素的聚合体

使用react开发的核心就是将页面拆分成若干个组件,并且react一个组件中同时耦合了css、js、image,这种模式整个颠覆了过去的传统的方式

(3) 单向数据流

其实reactjs的核心内容就是数据绑定,所谓数据绑定指的是只要将一些服务端的数据和前端页面绑定好,开发者只关注实现业务就行了

(4) JSX 语法

在vue中,我们使用render函数来构建组件的dom结构性能较高,因为省去了查找和编译模板的过程,但是在render中利用createElement创建结构的时候代码可读性较低,较为复杂,此时可以利用jsx语法来在render中创建dom,解决这个问题,但是前提是需要使用工具来编译jsx

react的语法使用

基础的dom操作

react既然是一个组件的抽象,所以我们写的页面也把他当成给一个抽象,然后把我们自己写的抽象的页面关联到需要展示的页面即可。思路就很清晰了,写一个抽象的组件,关联到需要展示的页面。

我们再看,一个前端的页面首先要访问的是哪个页面?那就是index.html,我们细看html内容

image-20220730155245859

发现,主要的就一个div标签,并且id是root,这个意思是不是我们找到这个root标签,往这个标签里插入组件,并且id是root的div,是不是很清晰了。react提供了我们想要的组件方法

1
2
3
4
5
6
7
// ReactDOM里有一个render方法,功能就是把组件渲染并且构造 DOM 树,然后插入到页面上某个特定的元素上
ReactDOM.render(
// 这里就比较奇怪了,它并不是一个字符串,看起来像是纯 HTML 代码写在 JavaScript 代码里面。语法错误吗?这并不是合法的 JavaScript 代码, “在 JavaScript 写的标签的”语法叫 JSX- JavaScript XML。
<h1>欢迎进入React的世界</h1>,
// 渲染到哪里
document.getElementById('root')
)

还记得,我们导入一个react的dom组件吗,这个是直接操作dom的组件,react都给我们封装好了,可以看到第一个参数就是我们的html语法,第二个是定位标签,我们需要给html插入到<div id="root"></div>,直接编辑运行到index.js。

image-20220730155940045

看下页面果然渲染上去了。

image-20220730160041991

这个时候,是不是思路就清晰了,我们主要渲染第一个参数,第二个参数就是一个绑定的效果,第一个参数可以当成一个组件的抽象,我们想么抽象就怎么抽象。但是,这样写的话,并符合抽象的概念,你见过谁的抽象写在一个参数里的?,那我们可以抽象一个方法直接引入即可

1
2
3
4
5
6
7
8
9
10
11
import React from 'react'
import ReactDOM from 'react-dom'


const App=()=><h1>hello world</h1>

ReactDOM.render(
<App/>
,
document.getElementById('root')
)

Class的组件

上面的方法已经很不错了,但是不够好,既然说到抽象组件,那我想写各种js引入进来不好吗,这种在符合组件的出现,react已经提供的方法,说到抽象永远要记住必须有一个可继承的抽象类,才会具有抽象的特性。语法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import React, { Component, Fragment } from 'react'
import ReactDOM from 'react-dom'

class Title extends Component{
render(){
return (
<h1>hello world</h1>
)
}
}

class App extends Component{
render(){
return (
<Fragment>
<Title />
</Fragment>
)
}
}


ReactDOM.render(
<App/>
,
document.getElementById('root')
)

为什么会有Fragment的标签,其实是react限制了所有的组件必须有一个大的父标签,所以需要一个标签给包裹住。

从而可以得知可以新建一个js文件,写class组件

1
2
3
4
5
6
7
8
9
10
11
import { Component } from "react";

class App extends Component{
render(){
return (
<h1>hhhhhhhhhhhhhhhhh</h1>
)
}
}

export default App;

函数式组件

有继承就有函数,如下,都是可导入直接引入即可

1
2
3
4
5
6
7
8
function HApp(){
return(
<h1>jjjjjjjjjjjjjjjjjjjjj</h1>
)
}


export default HApp;

index.js

1
2
3
4
5
6
7
8
9
10
import React from 'react'
import ReactDOM from 'react-dom'
import App from './02-函数式组件'


ReactDOM.render(
<App/>
,
document.getElementById('root')
)

非常方便,而方法的组件是无状态组件。