React是用于构建用户界面的JavaScript库, 核心专注于视图,目的实现组件化开发。
可组合:组件的组合使用。 可重复:一个组件反复使用。 可维护:每个组件很小 易于维护
全局安装
yarn add create-react-app -g
npm install create-react-app -g
创建项目 这里注意项目名称不能使用大写字母 以及关键字:如 react。 像如下的my-app
就可以。
creat-react-app my-app
进入到文件夹,启动
yarn start
npm start
初始化的项目启动后,会看到如下界面
我们看一下文件
引入了react的两个包,其中ReactDOM是去操作dom的,他的内容会更多一些。
import React from 'react';
import ReactDOM from 'react-dom/client';
是一种JS和HTML混合的语法、将组件的结构、数据、样式组合在一起
ReactDOM.render(
<h1>hello world</h1>,
// js语法 id选择器
document.getElementById('root')
)
我们借助babel看一下。
左面是我们的html语法,右边是React的Jsx语法。 babel。 因为浏览器是不识别JSX的,所以我们的React都经过了babel的转译
JSX 是一种语法糖,最终都会通过Babel转译为 createElement语法。
React元素 也就是虚拟DOM
我们打印一个虚拟DOM看一看
const element = React.createElement("h1",{
id:'title'
},'hello')
console.log(element,'elementelementelement')
实质上是一个对象。
JSX 编译成createElement是在webpack编译的时候,也就是打包的时候执行的。
我们打包一下
npm run build
然后去build文件去找,可以看到将虚拟DOM,编译成了 createElement
render方法负责把虚拟DOM转为真实DOM注入容器。
ReactDOM.render(elemet,document.getElemetById('root'))
在jsx中不使用calss 而需要使用className
let elemet = <h1 className='title'>hellow</h1>
不使用 style=""
,需要使用 style={{}}
相当于一个对象
let elemet = <h1 className='title' style={{color:'red'}}>hellow</h1>
这个属性用于输入框获得焦点
let elemet = <div><label htmlFor='title'/><input id='title'></div>
如果在JSX中读取JS变量的话,用 {}
let style = {background:'red'}
let elemet = <div style={style}></div>
let data = "我是文章"
let element = <span>{data}</span>
JSX其实是一个对象,可以在 if 或者 for 中使用。
import React from 'react';
import ReactDOM from 'react-dom';
function greeting(name){
if(name){
return <h1>hello,{name}</h1>
}else{
return <h2>hello,stranger</h2>
}
}
const element = greeting('yueyunpeng')
ReactDOM.render(element,document.getElementById('root'))
注意使用循环后,遍历生成的元素需要一个key属性,用于区分。
import React from 'react';
import ReactDOM from 'react-dom';
let persons = ['岳云鹏','雷佳音','沈腾']
let element = persons.map((name)=><li key={name}>{name}</li>)
ReactDOM.render(<ul>{element}</ul>,document.getElementbyId('root'))
把之前的虚拟DOM和新的虚拟DOM进行比较,只更新变化的。
如下 遍历users对象
let users = [{'name':'张三' },{'name':'李四'},{'name':'王保长'}]
// key 可以使用index索引
let element = users.map((user,index)=><li key={index}>{user.name}</li>)
ReactDOM.render(<ul>{element}</ul>,document.getElementbyId('root'))
当我们 数组中的对象顺序改变,便会通过DIFF算法 将之前的虚拟DOM与现在虚拟DOM进行比较。然后找到最简单的更改方式。如下:只需要把王保长的位置从第三个移到第一个
let users = [{'name':'王保长'},{'name':'张三' },{'name':'李四'}]
// key 可以使用index索引
let element = users.map((user,index)=><li key={index}>{user.name}</li>)
ReactDOM.render(<ul>{element}</ul>,document.getElementbyId('root'))
key是给React使用的,并不是给程序员使用的。key让组件有了唯一标识。相同的key React认为是同一个组件,这样后续相同的key对应组件都不会被创建。
如果两个元素的key相同,且元素类型相同,若元素属性变化,则React只更新组件对应的属性,这种情况下,性能开销会相对较小。如下的变化
<div style={{background:'red'}} key='same'></div>
<div style={{background:'blue'}} key='same'></div>
在render函数执行的时候,新旧两个虚拟DOM会进行对比,如果两个元素有不同的key,那么在前后两次渲染中就会被认为是不同的元素,这时候旧的元素会被unmount,新的元素会被mount
如果没有key得情况下,他直接会移除原先的第二个子元素,然后再append进去剩下的子元素,而其实我们这个操作只需要一个insert操作就能完成。为了解决这种问题,react需要我们提供给一个key来帮助更新,减少性能开销。
如果有key值得情况下,react就会通过key来发现tree2的第二个元素不是原先tree1的第二个元素,原先的第二个元素被挪到下面去了,因此在操作的时候就会直接指向insert操作,来减少dom操作的性能开销
如果我们用index来标识key,数组在执行插入、排序等操作之后,原先的index并不再对应到原先的值,那么这个key就失去了本身的意义,并且会带来其他问题。
key 的值以Math.random() 随机生成而定,这使得数组元素中的每项都重新销毁然后重新创建,有一定的性能开销