写在前面
之前在一家外包公司待过一段时间,那时候我只会用Vue,React没有深入研究,虽然我进去了,但是当时的项目是要用React,项目排期近在咫尺啊,做项目时出现问题,不知道怎么解决,其他人都在忙自己的,没有哪家公司让你进去是学习这个,都是一进去就让你做项目,做不出来只能怪你自己,无奈下我只能离职了。。。想想当时的自己挺失败的,以前太过于懒散了,把事情看得比较简单,实际并不是那样。为了以后能抓住机会,还是要努力奔跑。
学习目标
1.了解React
2.JSX简介
3.虚拟DOM
React
看过React官网的同学都知道,React 是一个用于构建用户界面的 JavaScript 库。
React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。
很多大厂都在使用React,当然进入大厂就是我现在的目标!React有很多优势,接下来讲解几点。
(1)React的主要优势之一就是组件化编写,这也是现代前端开发的一种基本形式。
(2)React 利用Virtual DOM ,同层虚拟DOM比较,每次渲染只渲染最少的DOM元素。
(3)React利用函数式编程的思维来解决用户界面渲染的问题,最大优势是提高开发效率,代码可维护和增强可阅读性。
(4)React强制所有组件由数据驱动渲染模式来工作,不管应用的规模多大,都能让程序处于可控范围内。
(5)...(后期总结再补上)
JSX简介
JSX就是Javascript和XML结合的一种格式(即Javascript的语法扩展)。
React 中的JSX 可以利用HTML语法来创建虚拟DOM,当遇到“<”JSX就当作HTML解析,遇到“{”就当作Javascript解析
组件和普通JSX语法区别:自定义的组件首字母必须大写,而JSX是首字母小写。
import React, { Component, Fragment } from 'react';
// 我们在作Flex布局的时候,外层还真的不能有包裹元素。这种矛盾其实React16已经有所考虑了,为我们准备了<Fragment>标签。
// 响应式设计和数据的绑定
// 构造函数constructor
import MenuCom from './menuCom';
import axios from 'axios';
class Menu extends Component {
constructor(props) {
super(props) // 继承父级(components)方法
this.state = {
inputVal: '',
list: ['微信读书', '电子读书']
}
}
// 决定一个组件该渲染啥
render() {
return (
<Fragment>
<div>
<div>
<label htmlFor='itemId'>添加菜单</label>
{/* 使用bind是为了绑定this指向,不绑定的话找不到this 直接在JSX部分,利用bind进行绑定就好。 */}
<input id='itemId' value={this.state.inputVal} onChange={this.inputChange.bind(this)} />
<button onClick={this.addMenu.bind(this)}>添加菜单</button>
</div>
</div>
<ul>
{
this.state.list.map((item, index) => {
// 绑定事件添加()
return (
<MenuCom
key={index + item}
index={index}
con={item}
// avname='借记卡'
deleteItem={this.deleteItem.bind(this)}
/>
)
})
}
</ul>
</Fragment>
)
}
}
export default Menu;
Virtual DOM
虚拟DOM 就是一个JS对象,用它来描述真实DOM。
(1)先了解一下DOM, DOM是结构化文本的抽象表达形式,在Web环境中,结构化文本是HTML文本,HTML中的每个元素都对应DOM中的节点,HTML元素是逐级包含的关系,所以DOM节点就构成了一个树形结构,成为DOM树。
(2)DOM树是对HTML的抽象,Virtual DOM是对DOM树的抽象。Virtual DOM不会触及浏览器的部分,只存在于JavaScript空间的树形结构,每次自上而下渲染React组件时,会对比这一次产生的Virtual DOM和上一次渲染的Virtual DOM ,然后修改有差别的部分真正的DOM树。
虚拟DOM原理
React虚拟DOM的大致流程:
1、state 数据 (this.state)
2、JSX 模版 (render函数)
3、数据 + 模版 结合,生成虚拟DOM
4、用虚拟DOM的结构生成真实的DOM,来显示 jsx -> js对象 ->真实的DOM
render() {
console.log('child render');
const {con} = this.props;
// jsx -> js对象 ->真实的DOM
return (
<li onClick={this.deleteClick}>
<span>{this.props.avname}{con}</span>
</li>
);
}
// jsx ->createElement ->虚拟DOM js对象 ->真实的DOM
render() {
return React.createElement('li', {}, React.createElement('span',{},'span'))
}
// JSX并不是真实的DOM 需要创建然后生成虚拟DOM再生成真实的DOM
5、state数据变化
6、数据+模版 生成新的虚拟DOM
7、比较原始的虚拟和新的虚拟DOM的区别,找到需要更改 的内容
8、直接操作DOM,改变更改的内容
Diff算法
(Diffrence 对比差异)
(1)逐层比较: 两个虚拟DOM做比对,一层层比较 若第一层一致,则比较第二层;若第一层比较有差异,则删除原始虚拟DOM下面的节点重新生成DOM替换原始的DOM; 同层比较算法简单,提高速度,减少两个算法的性能消耗这就是同层比较的好处。(2)key值比较: 给每个节点取对应的名字,不管你添加删除节点,其他的节点值是不变的,这样就可以直接比较不同的节点就OK。 key最好不要使用index不然节点对应的值就会改变。
key设置为index
<ul>
{
this.state.list.map((item, index) => {
// 绑定事件添加()
return (
<MenuCom
key={index}
index={index}
con={item}
deleteItem={this.deleteItem.bind(this)}
/>
)
})
}
</ul>
key为index的话,删除之后该节点的值会根据index的顺序更改
key设置为item<ul>
{
this.state.list.map((item, index) => {
// 绑定事件添加()
return (
<MenuCom
key={item}
index={index}
con={item}
deleteItem={this.deleteItem.bind(this)}
/>
)
})
}
</ul>
设置为item的话 item不会随着你的操作而更改
所以对比的时候会同层比较差异更改差异,这样会提升性能。
虚拟DOM的优点
1、虚拟DOM提升了性能,因为它减少了DOM操作。每次页面更新都是对组件的重新渲染,React借助虚拟DOM计算和比较DOM之间的差异这样就会只重新渲染需要更改的地方,从而提高性能。
2、使跨端应用得以实现。 React Native 写原生应用,因为有虚拟DOM。
3、后期补上...
最后
React学习的还不深入,目前先学习这些,有问题的小伙伴可以评论,我会及时回复,并改正自己的问题。