React学习笔记(四)


theme: channing-cyan

一.虚拟DOM与 DOM Diffing算法

1.验证DOM Diffing算法

废话不多说,先来看这样一个案例: ```js class Time extends React.Component{ state={ date:new Date() }

componentDidMount(){
        setInterval(()=>{
            this.setState({date : new Date()})
        },1000)
    }

    render(){
        return(
            <div>
                <span>Hello,
                <input type="text" />
                <h2>!It is:{this.state.date.toTimeString()}
                    <input type="text" />
                </h2>
                时间每隔一秒刷新一次 而h1和input标签不变化不重新渲染 所以在页面input中输入内容不被清空
            </span>
            </div>
        )
    }
}
ReactDOM.render(<Time />,document.getElementById('test'))

```

结果如图:

验证Diffing算法图.gif

2.1 key的作用

举个例子:

在一个组件中,我们先创建了两个对象,通过循环的方式放入<li>标签中,此时key使用的是index

如果生成的render出来后就不会改变里面的内容,那么你不需要指定key(不指定key时,React也会生成一个默认的标识),或者将index作为key,只要key不重复即可。

但是如果你的标签是动态的,是有可能刷新的,就必须显示的指定key。必须上面案使用map进行便利的时候就必须指定Key:

js this.state.num.map((n,index)=>{ return <div className="news" key={index} >新闻{n}</div> })

这个地方虽然显示的指定了key,但是官网并不推荐使用Index作为Key去使用;

这样会很有可能会有效率上的问题 举个例子:

在一个组件中,我们先创建了两个对象,通过循环的方式放入<li>标签中,此时key使用的是index

js person:[   {id:1,name:"张三",age:18},   {id:2,name:"李四",age:19} ] ​ this.state.person.map((preson,index)=>{    return  <li key = {index}>{preson.name}</li> })

如下图展现在页面中:

1611800406864.png

此时,我们想在点击按钮之后动态的添加一个对象,并且放入到li标签中,在重新渲染到页面中。

我们通过修改State来控制对象的添加。

js <button onClick={this.addObject}>点击增加对象</button> addObject = () =>{    let {person} = this.state;    const p = {id:(person.length+1),name:"王五",age:20};    this.setState({person:[p,...person]}); }

如下动图所示:

addObject.gif

这样看,虽然完成了功能。但是其实存在效率上的问题, 我们先来看一下两个前后组件状态的变化:

我们发现,组件第一个变成了王五,张三和李四都移下去了。因为我们使用Index作为Key,这三个标签的key也就发生了改变【张三原本的key是0,现在变成了1,李四的key原本是1,现在变成了2,王五变成了0】在组件更新状态重新渲染的时候,就出现了问题:

1611800988496.png 因为react是通过key来比较组件标签是否一致的,拿这个案例来说:

  • 首先,状态更新导致组件标签更新,react根据Key,判断旧的虚拟DOM和新的虚拟DOM是否一致
  • key=0的时候 旧的虚拟DOM 内容是张三 新的虚拟DOM为王五 ,react认为内容改变,从而重新创建新的真实DOM.
  • key=1的时候 旧的虚拟DOM 内容是李四,新的虚拟DOM为张三,react认为内容改变,从而重新创建新的真实DOM
  • key=2的时候 旧的虚拟DOM没有,创建新的真实DOM

这样原本有两个虚拟DOM可以复用,但都没有进行复用,完完全全的都是新创建的;这就导致效率极大的降低。

其实这是因为我们将新创建的对象放在了首位,如果放在最后其实是没有问题的,但是因为官方并不推荐使用Index作为key值,我们推荐使用id作为key值。从而完全避免这样的情况。

2.1基本原理图

11.png

3.关于key的经典面试题
  • react/vue中的key有什么作用?(key的内部原理是什么?)
  • 为什么遍历列表时,key最好不要用index?
4.1.1 虚拟DOM中key的作用
  • 简单的说: key是虚拟DOM对象的标识, 在更新显示时key起着极其重要的作用。

  • 详细的说: 当状态中的数据发生变化时,react会根据【新数据】生成【新的虚拟DOM】, 随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较,比较规则如下:

    • 旧虚拟DOM中找到了与新虚拟DOM相同的key:

      • 若虚拟DOM中内容没变, 直接使用之前的真实DOM
      • 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
    • 旧虚拟DOM中未找到与新虚拟DOM相同的key

      • 根据数据创建新的真实DOM,随后渲染到到页面
4.1.2 用index作为key可能会引发的问题
  • 1.若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
  • 2.如果结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题
  • 3.注意!如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的
4.1.3 开发中如何选择key?
  • 1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值
  • 2.如果确定只是简单的展示数据,用index也是可以的

二.React脚手架

2.1 使用 create-react-app 创建 react 应用
2.1.1 react脚手架
  • 1.xxx脚手架:用来帮助程序员快速创建一个基于xxx库的模板项目

    • 1.包含了所有需要的配置(语法检查、jsx编译、devServer...)
    • 2.下载好了所有相关的依赖
    • 3.可以直接运行一个简单效果
  • 2.react提供了一个用于创建react项目的脚手架军:create-react-app

  • 3.项目的整体技术架构为:react + webpack + es6 + eslint

  • 4.使用脚手架开发的项目的特点:模块化,组件化,工程化

2.1.2 创建项目并启动
  • 第一步,全局安装:npm i -g create-react-app
  • 第二步,切换到想创项目的目录,使用命令:create-react-app <project-name>
  • 第三步,进入项目文件夹:cd <project-name>
  • 第四步,启动项目:npm start
2.1.2 react脚手架项目结构
  • 我们主要来看看publicsrc整两个目录

  • public 1611817630266.png

  • src

1611818262317.png - 完整目录结构如下:

text |-node_modules ----- npm下载的相关依赖 |-public ----- 静态资源文件夹 | -css ------ css静态样式文件夹 | -favicon.icon ----- 网站页签图标 | -index.html ----- 主页面 | -logo192.png ------- logo图 | -logo512.png ------- logo图 | -manifest.json ----- 应用加壳的配置文件 | -robots.txt -------- 爬虫协议文件 |-src ----源码文件夹 | -App.css -------- App 组件的样式 | -App.js--------- App组件 | -App.test.js ----用于给App做测试 | -index.css ------样式 | -index.js.-----入口文件 | -logo.svg.------- logo图 | -reportWebMitals.js. |-package.json --- node包文件 包括项目的一些介绍 以及 相关文件版本 |-package.lock --- 依赖文件锁文件 |-README.md 自述文件

3.1.3 运行项目

执行npm run start后,看到这个页面,就说明项目运行成功了!!

1611816150630.png

三.参考

React官网: https://react.docschina.org/

尚硅谷视频: https://www.bilibili.com/video/BV1wy4y1D7JT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值