react学习一:react基础知识

React与vue.js的对比

组件化方面

什么是模块化:从 **代码** 的角度,去分析问题,把我们编程时候的业务逻辑,分割到不同的模块中来进行开发,这样能够**方便代码的重用**;

什么是组件化:从 **UI** 的角度,去分析问题,把一个页面,拆分为一些互不相干的小组件,随着我们项目的开发,我们手里的组件会越来越多,最后,我们如果要实现一个页面,可能直接把现有的组件拿过来进行拼接,就能快速得到一个完整的页面, 这样方**便了UI元素的重用**;**组件是元素的集合体**;

Vue是如何实现组件化的

.vue 组件模板文件,浏览器不识别这样的.vue文件,所以,在运行前,会把 .vue 预先编译成真正的组件;

template: UI结构

script: 业务逻辑和数据

style: UI的样式

React如何实现组件化

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

React中的组件,都是直接在 js 文件中定义的;

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

React核心概念

DOM

DOM的本质:就是用JS表示的UI元素

虚拟DOM(Virtual Document Object Model)

为什么要实现虚拟DOM:

比如要实现下面的表格排序案例:

react学习一:react基础知识_第1张图片

需求:实现一个点击表头,完成数据根据点击的列进行排序的功能

分析步骤

首先,我们这些所有的列表中渲染出来的数据,都在浏览器的内存中,以一个数组的形式存在;当点击每一个表头的时候,为这每一个表头绑定点击事件,在事件的处理函数中:根据点击的列名,对数组中的每一项进行排序,最终,排序好的新数组,就是我们将要展示到页面上的数据;(这一步完成后,数组是最新的,页面老的,并没有被刷新)

当得到排序好的数组之后,应该把最新的数组,更新到页面中去:使用原生的for循环手动拼接每个tr字符串,append到页面中,使用jquery、使用前端模板引擎;当我们拼好字符串后,就可以把最新的html字符串替换到页面上

上述的实现思路所存在的性能问题

只要数据发生了一点点变化,也会被强制重建整顿DOM树,这么做会导致很多元素的重绘和重排,导致性能浪费严重

如何解决上述问题

只要实现按需要更新页面上的元素即可,只需要把修改的数据,所对应的DOM元素重新构建一下,其他没有变化的数据,所对应的DOM节点不需要被强制更新

如何实现上述的解决方案(如何按需更新页面上的元素)

需要拿到页面被更新前的内存中的DOM树,同时,还要拿到页面更新前,新渲染出来的内存DOM树,然后,对比这两颗新旧DOM树,只需要找到那些需要被重新创建和修改的元素即可,这样就能实现DOM的按需更新

如何拿到这两颗新旧DOM树

如果要拿到浏览器中的DOM树,那么,我们必须要调用浏览器提供的相关js的api才行,但是浏览器并没有提供这样的api,既然浏览器没有提供这样的api,那么我们需要自己模拟这两颗新旧DOM树

如何模拟新旧两颗DOM树(如何自己模拟一个DOM节点

这是一个段落

手动模拟DOM树的原理:使用js创建一个对象,用这个对象,来模拟每个DOM节点,然后在每个DOM节点中,又提供了类似于children这样的属性,来描述当前DOM的子节点,这样,当DOM节点形成了嵌套关系,就模拟出了一颗DOM树

var p = {
    tagName : 'p',
    attrs : {
        title : '真的',
        id : ''
    },
    children : [
        '这是一个段落',
        {
            tagName : 'span',
            children : [
                '这是span'
            ]
        }
    ]
}

虚拟DOM的本质:就是使用js对象来模拟DOM树

虚拟DOM的目的:为了实现DOM节点的高效更新

DOM和虚拟DOM的区别

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

Diff算法

react学习一:react基础知识_第2张图片

tree diff:

新旧DOM树,逐层对比的方式,就叫做 tree diff,每当我们从前到后,把所有层的节点对比完后,必然能够找到那些 需要被更新的元素;

component diff:

在对比每一层的时候,组件之间的对比,叫做 component diff;当对比组件的时候,如果两个组件的类型相同,则暂时认为这个组件不需要被更新,如果组件的类型不同,则立即将旧组件移除,新建一个组件,替换到被移除的位置;

element diff:

在组件中,每个元素之间也要进行对比,那么,元素(a、span、div.....这种)级别的对比,叫做 element diff;

key:

key这个属性,可以把 页面上的 DOM节点 和 虚拟DOM中的对象,做一层关联关系;

React基本用法

安装两个包react和react-dom:

react 这个包,是专门用来创建React组件、组件生命周期等这些东西的;

react-dom 里面主要封装了和 DOM 操作相关的包,比如,要把 组件渲染到页面上

cnpm install react react-dom --save-dev

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

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

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

在 react 中,如要要创建 DOM 元素了,只能使用 React 提供的 JS API 来创建,不能【直接】像 Vue 中那样,手写 HTML 元素

React.createElement() 方法,用于创建 虚拟DOM 对象,它接收 3个及以上的参数

参数1: 是个字符串类型的参数,表示要创建的元素类型

参数2: 是一个属性对象,表示 创建的这个元素上,有哪些属性

参数3: 从第三个参数的位置开始,后面可以放好多的虚拟DOM对象,这写参数,表示当前元素的子节点

var myH1 = React.createElement('h1', null, '这是一个大大的H1')
var myDiv = React.createElement('div', { title: 'this is a div', id: 'mydiv' }, '这是一个div', myH1)

使用 ReactDOM 把元素渲染到页面指定的容器中:

ReactDOM.render('要渲染的虚拟DOM元素', '要渲染到页面上的哪个位置中')

注意: ReactDOM.render() 方法的第二个参数,和vue不一样,不接受 "#app" 这样的字符串,而是需要传递一个 原生的 DOM 对象

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

react学习一:react基础知识_第3张图片

你可能感兴趣的:(react)