day01日报(安装软件,构建思维导图,GET和POST的区别)
FSCapture录屏软件
- 目的: 是为了更方便的录制每天的日报产出,并且可以在后期去别的班级讲述项目逻辑或题目的思维逻辑,也能更好的保存视频,为以后的复习提高了便捷。
FreeMind思维逻辑软件
- 目的: 可以帮助我们创建、组织和管理自己的思维逻辑。
- 创建思维导图: 我们可以通过FreeMind创建和编辑的思维导图,我们可以使用节点来展示自己的想法或者计划,这些节点我们也可以用不同的颜色标记。
- 优化思路结构:可以帮助我们优化思路结构,让我们更加清晰的展现自己的想法和思路,优化他们的结构,使得思考过程更加有序和系统化,还可以用于项目管理,能够更好的掌握团队的成员的进度。
FreeMind简单使用技巧
- insert : 插入子节点
- enter : 插入兄弟节点
- ctrl+方向 : 调整节点位置
- 右键插入文件 :
作为程序员要怎么知道那些报错信息
- 使用百度翻译报错信息
- 使用网易有道翻译报错信息
GET和POST的区别?
- GET和POST都是HTTP协议中发送的请求方法。
- GET:
GET方法请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据 - POST:
POST方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用。
区别如下:
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST没有
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
- GET参数通过URL传递,POST放在Request body中
POST和PUT请求的区别?
- PUT请求是向服务器端发送数据,从而修改数据的内容,但是不会增加数据的种类,也就说无论进行多少次的PUT操作,其结果并没有不同。(可以理解为更新数据)
- POST请求是向服务器端发送请求,该请求会改变数据的种类等资源,它会创建新的内容。(可以理解为创建数据)
day02日报(计算机协议网络篇,每日约PK)
HTTP 协议
常见的HTTP请求头和响应头
HTTP Request Header常见的请求头:
- Accept : 浏览器能够处理的内容类型
- Accept-Charset : 浏览器能够显示的字符集
- Accept-Language : 浏览器当前设置的语言
- Accept-Encoding : 浏览器能够处理的压缩编码
- Connection : 浏览器与服务器之间连接的类型
- Cookie : 当前页面设置的任何Cookie
- Host : 发出请求的页面所在的域
- Referer : 发出请求的页面的URL
- User-Agent : 浏览器的用户代理字符串
HTTP Responses Header 常见的响应头:
- Date : 表示消息发送的时间
- server : 服务器名称
- Connection : 浏览器与服务器之间连接的类型
- Cache-Control : 控制HTTP缓存
- content-type : 表示后面的文档属于什么MIME类型
常见的Content-Type 属性值有以下四种:
- application/x-www-form-urlencoded : 浏览器的原生form表单,如果不设置enctype属性,那么最终就会以application/x-www-form-urlencoded方式提交数据。该方式提交的数据放在body里面,数据按照key1=val1&key2=val2的方式进行编码,key和val都进行了URL转码
- multipart/form-data : 该方式也是常见的POST提交方式,通常表单上传文件时使用该方式。
- application/json : 服务器消息主题时序列化后的JSON字符串。
- text/html : 该方式主要用来提交XML格式的数据。
HTTP状态码304是多好还是少好?
服务器为了提高网站的访问速度;对之前访问的部分页面指定缓存机制,当客户端在此对这些页面进行请求,服务器会根据缓存内容判断页面与之前的缓存是否相同,若相同的话便直接返回304,此时客户端调用缓存的内容,不必进行二次的下载或请求。
状态码304不应该认为是一种错误,而是对客户端有缓存情况下服务端的一种响应。
搜索引擎蜘蛛会更加青睐内容源更新频繁的网站。通过特定时间对网站抓取返回的状态码来调节对该网站的抓取频次。若网站在一定的时间内一直处于304的状态,那么蜘蛛可能会降低对网站的抓取次数。相反,若网站变化的频率非常之快,每次抓取都能获取新内容,那么日积月累的回访率也会提高。
产生较多的304状态码的原因:
- 页面更新周期长或不更新
- 纯静态页面或强制生成静态html
304状态码出现过多会造成一下问题:
- 网站快照停止;
- 收录减少;
- 权重下降;
常见的HTTP请求方法
- GET : 向服务器获取数据;
- POST : 将实体提交到指定的资源,通常会造成服务器资源的修改;
- PUT : 上传文件,更新数据;
- DELETE : 删除服务器上的对象数据;
- HEAD : 获取报文首部,与GET相比,不返回报文主体部分;
- OPTIONS : 询问支持的请求方法,用来跨域请求;
- CONNECT : 要求在与代理服务器通信时建立隧道,使用隧道进行TCP通信;
- TRACE : 回显服务器收到的请求,主要用于测试或诊断;
OPTIONS 请求方法及使用场景。
OPTIONS是除了GET和POST之外的其中一种HTTP请求方法。
OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。在请求方法的响应不能缓存。
OPTIONS请求方法主要用途有两个
- 获取服务器支持的所有HTTP请求方法;
- 用户检查访问权限。例如:在CORS跨域资源共享时,对于复杂请求,就是使用OPTIONS方法发送嗅探请求,以判断是否有对指定资源的访问权限。
说说HTTP1.0/1.1/2.0的区别?
一、 HTTP1.0 :
浏览器与服务只保持短暂的链接,浏览器的每次请求都需要与服务器建立一个TCP连接。
服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不会记录过去的请求,也就是说每次与服务器交互,都需要重新开一个连接。
如果说需要建立长连接,需要设置一个非标准的Connection字段 Connection:keep-alive;
二、HTTP1.1
在HTTP1.1中,默认支持长连接(Connection:keep-alive),即在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
建立一次连接,多次请求均有这一个连接来完成
这样,在加载html文件的时候,文件中多个请求和响应就可以在一个连接中传输。
同时,HTTP1.1还允许客户端不用等待上一次的请求结果返回,就看可以发出下一次请求,但服务端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。
同时,HTTP1.1在HTTP1.0的基础上,增加了更多的请求头和响应头来完善的功能,如下:
- 引入了更多的缓存控制策略,如If-Unmodefined-Since,If-Match,If-Node-Match等缓存头来控制缓存策略
- 引入range,允许值请求资源的某个部分
- 引入host,实现在一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟的WEB站点
并且还添加了其他的请求方法 : put、delete、options、head···
三、HTTP2.0
HTTP2.0在相比之前的版本,性能上有很大的提升,添加了
- 多路复用
- 二进制分帧
- 首部压缩
- 服务器推送
多路复用
HTTP/2 复用TCP连接,在一个连接,客户端和浏览器都可以同时发送多个请求和回应,而且不用按照顺序一一对应,这样就避免了“队头堵塞”
上图可以看到第四步中css、js资源是同时发送到服务端的
二进制分帧
帧是HTTP2通信中最小的单位信息 HTTP/2采用二进制格式传输数据,而非HTTP1.x文本格式,解析起来更高效
将请求和响应数据分割为更小的帧,并且它们采用了二进制编码
HTTP2中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流
每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧直接可以乱序发送,根据帧首部的流表识可以重新组装,这也是多路复用同时可以发送数据的实现条件
首部压缩
HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送
首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进的更新
例如: 下图中的两个请求,请求一发送了所有的头部字段,第二个请求则只需要发送差异数据,这样可以减少冗余数据,降低开销
服务器推送
HTTP2引入服务器推送,允许服务端推送资源给客户端
服务器会顺便把一些客户端需要的资源一起推送到客户端,如在响应一个页面请求中,就可以随同页面的其他数据
免得客户端再次创建连接发送请求到服务器端获取
这种方式非常适合加载静态资源
四、总结
HTTP1.0 :
- 浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接
HTTP1.1 :
- 引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用
- 在同一个TCP连接里面,客户端可以同时发送多个请求
- 虽然允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的,服务器只有处理完一个请求,才会接着处理下一个请求。如果前面的处理的特别慢,后面就会有许多请求排队等着。
- 新增了一些请求方法
- 新增了一些请求头和响应头
HTTP2.0 :
- 采用二进制格式而非文本格式
- 完全多路复用,而非有序并阻塞、只需一个连接即可实现并行
- 使用报头压缩,降低开销
- 服务器推送
面试问题(算法、八股文、项目)
算法题
1.手写深拷贝
let obj = [
aa:'1111',
list:[
{id:1,age:12},
{id:2,age:32},
],
aaa:{name:'张三'}
]
function deepCopy(obj){
let newObj =null;
if(typeof(obj) =='object' && obj!==null){
newObj = obj instanceof Array ?[]:{}
for(var i in obj){
newObj[i]=deepCopy(obj[i])
}
}else{
newObj = obj
}
return newObj
}
2.数组去重
let arr = [1, 1, 2, 2, 3 ,4]
function arrQuchong(arr){
return arr.reduce((prev,next)=>{
if(prev.indexOf(next)==-1){
prev.push(next)
}
return prev
},[])
}
3.扁平化结构转为树形结构
let data = [
{id:1,pid:0,name:'张三'},
{id:2,pid:1,name:'李四'},
{id:3,pid:2,name:'李三'},
{id:4,pid:3,name:'王五'},
{id:5,pid:4,name:'果酸'},
{id:6,pid:6,name:'事件'},
{id:7,pid:null,name:'破三'},
]
function bianPing(data){
let arr =[];
let map ={};
data.forEach(item => map[item.id] =item)
data.forEach((item)=>{
let keys = map[item.pid]
if(keys){
keys.children ||(keys.children=[])
keys.children.push(map[item.id])
}else{
arr.push(map[item.id])
}
})
return arr
}
4.圆周率转为中文
let pai = Math.PI
function tocn(num){
return (num + '').split.map(item=>{
return item == '.' ? '点' : '一二三四五六七八九'[item]
}).join()
}
八股文
HTTP是什么?HTTP和HTTPS的区别?
一、HTTP
HTTP(HyperText Transfer Protocol) ,即超文本运输协议,是实现网络通信的一种规范 HTTP 特点 :
- 支持客户/服务器模式
- 简单快速 : 客户向服务器请求服务时,只需要传送请求方法和路径。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快
- 灵活 : HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记
- 无连接 : 无连接的含义是限制每次链接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开链接。采用这种方式可以节省传输的时间
- 无状态 : HTTP协议无法根据之前的状态进行本次的请求处理
二、HTTPS
HTTP传递信息是以文明的形式发送内容,这并不安全。而HTTPS出现是为了解决HTTP不安全的特性。
为了保证这些隐私的数据能加密传输,让HTTP运行安全的SSL/TLS协议上,即HTTPS = HTTP + SSL/TLS,通过SSL证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密
SSL协议位于TCP/IP协议与各种应用层协议之间,浏览器和服务器在使用SSL建立连接时需要选择一组恰当的加密算法来实现安全通信,为数据通信提供安全支持
流程图如下:
- 首先客户端通过URL访问服务器建立SSL连接
- 服务端收到客户端请求后,会将支持的证书协议(证书包含公钥)传送一份给客户端
- 客户端的服务器开始协商SSL连接的安全等级,也就是信息加密的等级
- 客户端的浏览器根据双方同意的安全等级,建立会话秘钥,然后利用网站的公钥将会话秘钥加密,并传送给网站
- 服务器利用自己的私钥解密出会话秘钥
- 服务器利用会话秘钥加密与客户端之间的通信
三、区别
- HTTPS是HTTP协议的安全版本,HTTP协议的数据传输是明文的,是不安全的,HTTPS使用了SSL/TSL协议进行了加密处理,相对更加安全
- HTTP和HTTPS使用的连接方式不同,默认的端口号也不同,HTTP是80,HTTPS是443
- HTTPS由于需要设计加密以及多次握手,性能方面不如HTTP
- HTTPS需要SSL,SSL证书需要钱,功能越强大的证书费用越高
地址栏输入URL后回车会发生什么
一、简单分析
首先是简单的分析如下 :
- URL解析
- DNS查询
- TCP链接
- HTTP请求
- 响应请求
- 页面渲染
二、详情分析
URL解析
首选判断你输入的是一个合法的URL还是一个待搜索的关键词,并且根据你输入的内容进行对应的操作
DNS查询
查询过程如下图所示:
最终获取到域名对应的目标服务器IP地址
TCP连接
tcp是一种面向有连接的传输层协议
在确定目标服务器的IP地址后,则经历三次握手建立TCP连接,流程如下图所示 :
发送http请求
当建立tcp连接之后,就可以在这基础上进行通信,浏览器发送http请求到目标服务器
请求的内容包括:
- 请求行
- 请求头
- 请求主题
响应请求
当服务器接收到浏览器的请求之后,就会进行逻辑操作,处理完成之后返回一个HTTP响应消息,包括 :
- 状态行
- 响应头
- 响应正文
在服务器响应之后,由于现在http默认开始长连接keep-alive,当关闭之后,tcp链接则会经过四次握手完成断开
页面渲染
当浏览器接收到服务器响应的资源后,首先会对资源进行解析:
- 查看响应头的信息,根据不同的指示做对应的处理,比如重定向,存储cookie,解压gzip,缓存资源等等
- 查看响应头的Content-Type的值,根据不同的资源类型采用不同的解析方式
关于页面的渲染过程如下:
- 解析HTML,构建DOM树
- 解析CSS,生成CSS规则树
- 合并DOM树和CSS规则,生成render树
- 布局render树(Layout/reflow),负责元素尺寸、位置的计算
- 绘制render树(paint),绘制页面像素信息
- 浏览器会将各层的信息发送给GPU,GPU会将各层合并(composite),显示在屏幕上
CDN的原理
CDN(Content Delivery Network)即内容分发网络,是一种通过全球多个节点部署服务器,将内容快速分发给全球用户的技术。其主要的原理包括以下几点:
1.缓存 : 当用户访问某个网站时,请求由离用户最近的节点服务器处理,并将内容缓存在该服务器上,下次用户访问同样的内容时,就可以直接从缓存中获取,大大提高的访问速度。
2.负载均衡 : CDN将流量分散到多个节点服务器上,避免了单个服务器的负载过重而导致请求响应缓存慢或服务器瘫痪。
3.动态路由 : CDN会将会根据实际情况自动调整路由,选择响应速度较快的链路,来保证数据的快速传输和及实响应。
4.协议优化 : CDN会根据HTTP协议进行优化,例如使用TCP加速、支持gzip压缩、减少了TCP握手次数等,也有些还支持HTTPS协议传输加密数据。
5.多级缓存 : CDN中使用了多级缓存机制,将缓存信息分为本地缓存、边缘缓存和中央缓存等多个级别,提高了缓存效率和命中率。
综上所述,CDN通过全球多个节点分布式部署服务器,采用负载均衡策略、动态路由、协议优化等技术手段,使得全球用户能够快速、安全的访问网站的内容、提高网站的性能、可靠性和稳定性。
说一说js中隐式类型转换,举例说明
1.字符串与数字的隐式转换 var num = '123' + 456 string+number =string
2.布尔值与其他类型的隐式转换 在需要信息比较时,js会将非布尔值转为布尔值true或false if(10){ console.log("js 将数字10转为布尔值true") } if(""){ console.log("js 将空字符串转为布尔值false") }
3.加减乘除存在隐式转换
day03(HHTP结尾)
如何理解OSI七层模型?
OSI (Open System Interconnect)模型全称为开放式通信系统互连参考模型,是国际标准化组织(ISO)提出的一个试图使各种计算机在全世界范围内互连为网络的标准框架。
OSI将计算机网络体系结构划分为七层,每一层实现各自的功能和协议,并完成与相邻层的接口通信。即每一层扮演的角色,互不打扰。
OSI七层模型分为:
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
应用层
OSI参考模型中最靠近用户的一层,是为了计算机用户提供应用接口,也是为用户之间提供各种网络服务。我们常见的应用层网络服务协议有:HTTP,HTTPS,FTP,POP3,SMTP 等。
- 在客户端与服务器中经常会有数据的请求,这个时候就会用到http或者https在后端设计数据接口时,我们常常使用到这个协议。
- FTP是文件传输协议,在开发过程中,个人并没有涉及到,但是我想,在一些资源网站,比如百度网盘··迅雷 应该是基于协议的。
- SMTP是simple mail transfer protocol(简单邮件传输协议)。在一个项目中,在用户邮箱验证码登录的功能时,使用到这个协议。
表示层
表示层提供各种用于应用层数据的编码和转化功能,确保一个系统的应用层发生的数据能被另一个系统的应用层识别。如果必要,该层可提供一种标准表示形式,用于计算机内部的多种数据格式转换成通信中采用的标准形式。数据压缩和加密也是表示层可提供的转换功能之一。
在项目开发中,为了方便数据传输,可以使用base64对数据进行编解码。如果按功能来划分,base64应该是工作在表示层
会话层
会话层就是负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。
传输层
传输层建立了主机端的链接,传输层的作用是为了上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽下层数据通信的细节,使高层用户看到的只是在两个传输实体间的一条主机的,可由用户控制和设定的、可靠的数据通信。我们通常说的,TCP UDP就是这一层。端口号即是这里的"端"。
网络层
本层通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适的路由和交换节点,正确无误地按照传送给目的端的运输层。就是通常说的IP层,这一层就是我们经常说的IP协议层,IP协议Internet的基础。我们可以这样理解,网络层规定了数据包的传输路线,而传输层规定了数据包的传输方式。
数据链路层
将比特组合成字节,再将字节组合成帧,使用链路层地址(以太网使用MAC地址)来访问介质,并进行差错检测。
网络层与数据链路层的对比,通过上面的苗氏,我们或许可以这样理解,网络层是规划了数据包的传输路线,而数据链路层就是传输路线。不过,在数据链路层上还增加了差错控制的功能。
物理层
实际最终信号的传输是通过物理层实现的。通过物理介质传输比特流。规定了电平、速度和电缆针脚。常用设备有(各种物理设备)集线器、中断器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输介质。
OSI七层模型通信的特点:对等通信
对等通信,为了使数据分组从源传送到目的地,源端OSI模型的每一层都必须与目的端的对等层进行通信,这种通信方式称为对等层通信。在每一层通信的过程中,使用本层自己协议进行通信。
TCP/IP五层协议
TCP/IP五层协议和OSI的七层协议对应关系如下:
- 应用层(application layer):直接为应用进程提供服务。应用层协议定义的是应用进程间通讯和交互的规则,不同的应用有着不同的应用层协议,如HTTP协议(万维网服务)、FTP协议(文件传输)、SMTP(电子邮件)、DNS(域名查询)等。
- 传输层(transport layer):有事也译为运输层,他负责两台主机中的进程提供通信服务。该层主要有以下两种协议:
- 传输控制协议(Transmission Control Protocol,TCP):提供面向链接的、可靠的数据服务传输服务,数据传输的基本单位是报文段(segment);
- 用户数据报协议(User Datagram Protocal,UDP):提供无连接的、尽最大努力的数据传输服务,但不保证数据传输的可靠性,数据传输的基本单位是用户数据报。
- 网络层(internet layer) :有时也译为网际层,他负责为两台主机提供通信服务,并通过选择合适的路由将数据传递到目标主机。
- 数据链路层(data link layer) :负责将网络层交下来的IP数据报封装成帧,并在链路的两个相邻节点传送帧,每一帧都包含数据和必要的控制信息(如同步信息、地址信息、差错控制等)。
- 物理层(physicl Layer) :确保数据可以在各种物理媒介上进行传输,微数据的传输提供可靠的环境。
从上图可以看出,TCP/IP模型比OSI模型更加简洁,他把应用层/表示层/会话层 全部结合为了应用层。
在每一层都工作着不同的设备,比如我们常用的交换机就工作在数据链路层的,一般的路由器是工作在网络层的。
在每一层实现的协议也各不同,即每一层的服务也不同,下图列出了每层主要的传输协议:
同样。TCP/IP五层协议的通信方式也是对等通信:
day04(新面试题)
new操作符实现原理
在js中,使用new操作符可以创建一个对象实例。new操作符的实现原理可以归纳为以下几个步骤:
1.创建一个新对象。这个新对象会继承自构造函数的prototype属性。
2.将函数的this指向这个新的对象。
3.指向构造函数内部的代码,以对这个新对象进行初始化操作。
4.如果构造函数返回一个对象,则返回该对象;否则返回步骤1创建新的对象。
下面是一段模拟实现new操作符的代码:
function myNew(constructor,...args){
// 创建一个对象,继承自构造函数的prototype属性
const obj =Object.create(constructor.prototype)
// 将函数的this指向这个新的对象,并执行构造函数内部的代码
const result =constructor.apply(obj,args)
// 如果构造函数返回一个对象,则返回该对象;否则返回步骤1创建新对象
returen typeof result ==='object' ? result :obj
}
在该函数中,首先使用 Object.create() 方法创建一个新对象 obj,使其继承自构造函数 constructor 的 prototype 属性。
然后使用 apply() 方法调用 constructor 函数,将 this 指向 obj,并将参数列表 args 展开作为构造函数的实参传入。
最后,如果构造函数返回的是一个对象,则直接返回该对象;否则返回新创建的对象 obj。
需要注意的是,使用 new 操作符创建实例时,如果构造函数内部没有显式返回任何值或者返回的是一个基本数据类型,则会忽略返回值并返回步骤 1 所创建的新对象。只有在构造函数返回一个对象时,new 操作符才会返回这个对象。
讲解useEffect
useEffect是React Hooks提供的一个函数,它用于在函数组件中执行副作用操作,例如发送网络请求、访问本地存储、添加或移除DOM元素等。它与类组件中的cmponentDidMount、componentDidUpdate和componentWillUNmount生命周期类似,但是使用的方式有一些不同。
useEffect函数接受两个参数:第一个参数就是回调函数,第二个参数是一个数组,用于指定依赖项。当依赖项数组中的任何一个值发生变化的时候,useEffect回调函数就会重新执行。
useEffect接收一个函数参数和一个可选的依赖数组参数。当组件被渲染到页面上,React会执行useEffect中传入的函数。当组件更新时,React也会检查数组是否发生变化。如果依赖数组中的任何一个值发生变化,React将重新执行useEffect中的函数,如果依赖数组为空,则说明该效果不依赖于任何变量,只会在组件加载和卸载时执行。
1.不传递第二个参数
当没有传递依赖数组时,useEffect中函数在每次渲染完成后都会被调用,这意味着在每次渲染后都会执行副作用代码,可能会导致性能问题。例如,如果在useEffect中设置了一个定时器,在每次渲染后都会创建一个新的定时器,导致内存泄露。 **没有第二个参数的时候componentMount,componentWillUnmount,componentDidUpdate都会被触发。
import React, { useState, useEffect } from 'react';
function Timer() { const [time, setTime] = useState(0);
useEffect(() => { const timer = setInterval(() => { setTime(time + 1); }, 1000); return () => clearInterval(timer); });awd
return <div>{time}</div>; }
在这个例子中,我们定义了一个计数器 time 和一个用于设置定时器的 useEffect。在每次渲染完成后,useEffect 中的函数都会被调用,即使没有传递第二个参数。在函数组件被卸载时,React 会自动清理定时器,避免内存泄漏。
2.传递空数组作为第二个参数
如果传递一个空数组作为依赖项,useEffect中的函数只在组件加载时执行一次,类似于componentDidMount。这样可以避免在每次渲染的时执行副作用代码。
import React, { useState, useEffect } from 'react';
function Timer() { const [time, setTime] = useState(0);
useEffect(() => { const timer = setInterval(() => { setTime(time + 1); }, 1000);
return () => clearInterval(timer); }, []); return <div>{time}</div>; }
在这个例子中,我们传递一个空数组作为第二个参数,这意味着 useEffect 中的函数只会在组件加载时执行一次。
3.在依赖项数组中传入变量
如果需要根据一个或多个变量的变化来执行副作用代码,可以把这些变量作为依赖项传递给useEffect。
import React, { useState, useEffect } from 'react';
function Timer() {
const [time, setTime] = useState(0);
const [paused, setPaused] = useState(false); useEffect(() => { if (!paused) { const timer = setInterval(() => { setTime(time + 1); }, 1000); return () => clearInterval(timer); } }, [time, paused]);
return ( <div> <div>{time}</div> <button onClick={() => setPaused(!paused)}> {paused ? 'Start' : 'Pause'} </button> </div> ); }
在这个例子中,我们定义了一个计数器 time 和一个状态 paused。每当 paused 发生变化,React 就会重新执行 useEffect 中的函数。在 useEffect 函数中,我们根据 paused 的值来决定是否启动计时器