React入门 - 从零开始学React

1,545 阅读7分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

ReactJS简介

  • React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了
  • react只关注于视图层,官方对react的定位是:用于构建用户界面的 JavaScript 库
  • 最流行的一门框架。轻量级前端框架(其实Vue也算是),支持JSX(JavaScript XML)语法,jsx是js内定义的一套XML语法,最终被解析成js。在JSX中可以将HTML于JS混写;同样采用虚拟DOM,高效。

React与vue.js的对比

虚拟Dom

  • Vue的虚拟dom是基于snabbdom库所做的修改,为了保证页面的最小优化,snabbdom引入了diff算法,通过Diff算法找出前后两个虚拟DOM之间的差异,只更新改变了的DOM节点,而不重新渲染为改变的DOM节点。
  • react定义的一种类似于XML的JS扩展语法:JSX。作用是用来创建react虚拟DOM。

组件化方面

  1. 模块化:从 代码 的角度,去分析问题,把我们编程时候的业务逻辑,分割到不同的模块中来进行开发,这样能够方便代码的重用
  2. 组件化:从 UI 的角度,去分析问题,把一个页面,拆分为一些互不相干的小组件,随着我们项目的开发,我们手里的组件会越来越多,最后,我们如果要实现一个页面,可能直接把现有的组件拿过来进行拼接,就能快速得到一个完整的页面, 这样方便了UI元素的重用组件是元素的集合体
  3. Vue是如何实现组件化的:.vue 组件模板文件,浏览器不识别这样的.vue文件,所以,在运行前,会把 .vue 预先编译成真正的组件;
  • template: UI结构
  • script: 业务逻辑和数据
  • style: UI的样式

4.React如何实现组件化:在React中实现组件化的时候,根本没有 像 .vue 这样的模板文件,而是,直接使用JS代码的形式,去创建任何你想要的组件;

  • React中的组件,都是直接在 js 文件中定义的;
  • React的组件,并没有把一个组件 拆分为 三部分(结构、样式、业务逻辑),而是全部使用JS来实现一个组件的;(也就是说:结构、样式、业务逻辑是混合在JS里面一起编写出来的)

移动APP开发

  • Vue,结合 Weex 这门技术,提供了 迁移到 移动端App开发的体验
  • React,结合 ReactNative,提供了迁移到 移动App的开发体验(RN用的最多,也是最火最流行的);

轻量化

都把注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。(vue-router、vuex、react-router、redux等等)

React中几个核心的概念

虚拟DOM(Virtual Document Object Model)

  • DOM的本质是什么:Document Object Model 页面元素 JS表示的UI界面元素

  • DOM和虚拟DOM的区别:

    • DOM是由浏览器中的JS提供功能,所以我们只能人为的使用 浏览器提供的固定的API来操作DOM对象;
    • 虚拟DOM:并不是由浏览器提供的,而是我们程序员手动模拟实现的,类似于浏览器中的DOM,但是有着本质的区别;
  • 为什么要实现虚拟DOM:

    • JavaScript需要借助浏览器提供的DOM接口才能操作真实DOM,修改DOM经常导致页面重绘,所以一般来说,DOM操作越多,网页的性能就越差
    • 真实的DOM中,过多的内容修改,会带来多次的页面重绘,极大的损耗页面的性能。
    • 而在使用虚拟DOM时,不管一次修改了多少内容,最后只会发生一次页面的重绘,大大的提高了页面的性能。
    • 虚拟DOM设计的核心就是用高效的js操作,来减少低性能的DOM操作,以此来提升网页性能。
  • 虚拟DOM的目的:

    • 虚拟DOM并不能消除原生的DOM操作,你仍然需要通过浏览器提供的DOM接口来操作真实DOM树,才能使页面发生改变。虚拟DOM的设计似乎是多此一举。
    • 但是虚拟DOM带来了一个重要的优势,那就是我们可以在完全不访问真实DOM的情况下,掌握DOM的结构
    • 如果我们本打算手动进行三次真实DOM操作,有了虚拟DOM结构后,把这三次DOM操作简化成了一次,这不就带来了性能上的提升

    image-20210119062925366.png

  • React中的虚拟dom

    • React中使用jsx语法定义模板时,React会用它生成一个由JavaScript描述的虚拟DOM树,并将其保存在JavaScript内存中。这个虚拟DOM树还保留了我们在模板中定义的数据和视图的绑定关系,这为React自动根据数据变化更新视图提供了可能。随后当数据发生变化时,React重新生成一个虚拟DOM树,通过对比两个虚拟DOM树的差异,React就可以知道该如何高效地更新视图。接着它就会调用原生的DOM接口,去更新真实DOM。

Diff算法

diff算法其实就是对DOM进行different比较的一种算法

  • tree diff:新旧DOM树,逐层对比的方式,就叫做 tree diff,每当我们从前到后,把所有层的节点对比完后,必然能够找到那些 需要被更新的元素;
  • component diff:在对比每一层的时候,组件之间的对比,叫做 component diff;当对比组件的时候,如果两个组件的类型相同,则暂时认为这个组件不需要被更新,如果组件的类型不 同,则立即将旧组件移除,新建一个组件,替换到被移除的位置;
  • element diff:在组件中,每个元素之间也要进行对比,那么,元素级别的对比,叫做 element diff;
  • key:key这个属性,可以把 页面上的 DOM节点 和 虚拟DOM中的对象,做一层关联关系; Diff算法图

React项目的创建

react.docschina.org/

Diff.png

react.docschina.org/docs/create…

Create React App

npx create-react-app my-app
cd my-app
npm start
SKIP_PREFLIGHT_CHECK=true

项目启动效果图

createapp.png

react.docschina.org/docs/render…

1.在项目中导入两个相关的包:

// 1. 在 React 学习中,需要安装 两个包 react  react-dom
// 1.1 react 这个包,是专门用来创建React组件、组件生命周期等这些东西的;
// 1.2 react-dom 里面主要封装了和 DOM 操作相关的包,比如,要把 组件渲染到页面上
import React from 'react'
import ReactDOM from 'react-dom'

2.使用JS的创建虚拟DOM节点:

    // 2. 在 react 中,如要要创建 DOM 元素了,只能使用 React 提供的 JS API 来创建,不能【直接】像 Vue 中那样,手写 HTML 元素
    // React.createElement() 方法,用于创建 虚拟DOM 对象,它接收 3个及以上的参数
    // 参数1: 是个字符串类型的参数,表示要创建的元素类型
    // 参数2: 是一个属性对象,表示 创建的这个元素上,有哪些属性
    // 参数3: 从第三个参数的位置开始,后面可以放好多的虚拟DOM对象,这写参数,表示当前元素的子节点
    // <div title="this is a div" id="mydiv">这是一个div</div>
​
    var myH1 = React.createElement('h1', null, '这是一个大大的H1')
    
    
    var myDiv = React.createElement('div', { title: 'this is a div', id: 'mydiv',className:"duv" }, '这是一个div', myH1)
​
    
  1. 使用 ReactDOM 把元素渲染到页面指定的容器中:
    // ReactDOM.render('要渲染的虚拟DOM元素', '要渲染到页面上的哪个位置中')
    // 注意: ReactDOM.render() 方法的第二个参数,和vue不一样,不接受 "#app" 这样的字符串,而是需要传递一个 原生的 DOM 对象
    ReactDOM.render(myDiv, document.getElementById('app'))

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
​
// 创建虚拟dom节点
let myli = React.createElement('li',null,'我是li')
let myul = React.createElement('ul',{className:'list'},myli)
ReactDOM.render(
  // <React.StrictMode>
  //   <App />
  // </React.StrictMode>,
  // 渲染指定dom
  myul,
  document.getElementById('root')
);
​
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
​