面试题--小小总结

文章目录


前言

面试题很重要,持久更新!!!

一、说说javascript内存泄漏的几种情况?


1、忘记关闭的定时器
2、意外的全局变量
3、使用不当的闭包
4、网络回调
5、忘记清除的dom元素

二、说说如何借助webpack来优化前端性能


webpack是一个强大的前端打包工具,可以通过配置来优化前端性能,具体的优化方式如下:

  1. 代码压缩:使用UglifyJSPlugin对js代码进行压缩,使用optimize-css-assets-webpack-plugin对css代码进行压缩,减小代码体积,提高网页加载速度
  2. 代码分离:使用webpack的代码分离功能将代码分成多个小块,实现按需加载,减少首屏加载时间
  3. 按需加载:使用react-router的按需加载功能,比如react.lazy,可以减少首屏加载时间
  4. 静态资源优化:使用file-loader和url-loader对图片和其他静态资源进行打包和优化,减少http请求
  5. 缓存优化:使用webpack的chunkhash和contenthash功能对文件进行版本控制,从而实现缓存优化,减少不必要的文件下载
  6. 代码检查:使用eslint-loader对JS代码进行检查,避免低级错误和代码冗余,提高代码质量和性能
  7. 预编译器优化:使用sass-loader和less-loader对css进行预编译,提高编写效率和代码复用

三、说说webpack中代码分割如何实现?


webpack中的代码分割是通过将代码拆分成更小的块,以便运行时按需加载。这可以减少初始加载时间并提高应用程序的性能。webpack支持两种类型的代码分割:同步和异步

同步代码分割:是指在构建时将代码分成更小的块,这样可以将应用程序初始加载时间分散到多个块中。在webpack中,可以使用SplitChunksPlugin插件来实现同步代码分割,该插件将重复模块拆分成一个单独的文件,使得多个模块之间可以共享这个文件,从而减少了初始加载时间。

异步代码分割:是指在运行时将代码拆分成更小的块,这样可以按需加载块,而不是在初始加载时一次性加载所有代码。在webpack中可以使用import()函数或dynamic import语法来实现异步代码分割。这些函数和语法允许你在需要时异步加载代码块

总结:webpack分割代码有两种方式:
①同步分割是指在构建时将代码拆分成更小的块,使用SplitChunkPlugin插件可以实现,该插件将重复的模块拆分成一个单独的文件,使得多个模块共享这个文件,从而减少了代码量和初始加载时间。
②异步分割是指在运行时将代码拆分成更小的块,可以按需加载,而不是一次性加载所有代码,可以使用import()函数或dynamic import语句来实现异步代码分割

四.如何通过原生js实现一个节流函数和防抖函数,写出核心代码


节流函数的实现思路是在一定时间内只执行一次函数,可以通过setTimeout来实现

function throttle(fn,delay){
	let timer = null
	return function(){
		const context = this;
		const args = arguments;
		if(!timer){
			timer=setTimeout(function(){
				fn.apply(context,args);
				timer = null
			},delay)
		}
	}
}

防抖函数的实现思路是在一定时间内只执行最后一次函数,可以通过clearTimeout和setTimeout来实现

function debounce(fn,delay){
	let timer = null;
	return function(){
		const context = this;
		const args = arguments;
		if(timer){
			clearTimeout(timer)
		}
		timer=setTimeout(function(){
			fn.apply(context,args)
		},delay)
	}
}

五、说说你对fiber架构的理解?解决了什么问题?


React Fiber 是 Facebook 花费两年余时间对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现 。增加了优先级,优先级高的任务可以中断优先级低的任务,再重新执行优先级低的任务,增加了异步任务,dom diff树变成了链表
解决了页面长时间不更新导致的页面响应度差,用户感觉到卡顿的问题

六、 说说你对useEffect的理解,可以模拟哪些生命周期?

使用钩子函数useEffect可以实现组件的副作用
useEffect(希望执行的动作,[组件状态的列表])
第二个参数是用来处理useEffect的调用的时机,是一个数组,数组内是组件状态的列表
1、useEffect模拟componentDidMount
2、useEffect模拟componentDidUpdate
3、useEffect模拟componentWillUnmount

七、 说说 Real DOM 和 Virtual DOM 的区别?优缺点?两者的区别如下:

虚拟 DOM 不会进行排版与重绘操作,而真实 DOM 会频繁重排与重绘
虚拟 DOM 的总损耗是“虚拟 DOM 增删改+真实 DOM 差异增删改+排版与重绘”
真实 DOM 的总损耗是“真实 DOM 完全增删改+排版与重绘”
真实 DOM 的优势:易用
缺点:效率低,解析速度慢,内存占用量过高
性能差:频繁操作真实 DOM,易于导致重绘与回流使用虚拟 DOM 的优势如下:
简单方便:如果使用手动操作真实 DOM 来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难
性能方面:使用 Virtual DOM,能够有效避免真实 DOM 数频繁更新,减少多次引起重绘与回流,提高性能
跨平台:React 借助虚拟 DOM,带来了跨平台的能力,一套代码多端运行
缺点:
在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化
首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,速度比正常稍慢

八、 说说你对React中虚拟dom的理解?


Virtual DOM是一种编程概念。通俗点理解,虚拟DOM是一棵虚拟的JavaScript对象树,画重点,”虚拟的“、”JS对象“,指的是它把真实的网页文档节点,虚拟成一个个的js对象,并以树型结构,保存在内存中。

九、说说你对react hook的理解?

React hooks:就是用函数的形式代替换来的继承类的形式,并且使用预函数的形式管理state,有hooks可以不再使用类的形式定义组件了Hooks优点:告别难以理解的class(this和生命周期的痛点)
解决业务逻辑难以拆分的问题
使状态逻辑复用变得简单可行
函数组件从设计思想上来看更加契合react的理念React hooks常用的四个钩子UseState(),useContext(),useEffect(),useReducer()

十、 说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?

挂载阶段:
constructor() 在 React 组件挂载之前,会调用它的构造函数。
componentWillMount: 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
componentDidMount(): 在组件挂载后(插入 DOM 树中)立即调用
更新运行阶段:
componentWillReceiveProps: 在接受父组件改变后的props需要重新渲染组件时用到的比较多,外部组件传递频繁的时候会导致效率比较低
shouldComponentUpdate():用于控制组件重新渲染的生命周期,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新
render(): render() 方法是 class 组件中唯一必须实现的方法。
componentWillUpdate(): shouldComponentUpdate返回true以后,组件进入重新渲染完成之前进入这个函数。
componentDidUpdate(): 每次state改变并重新渲染页面后都会进入这个生命周期
卸载或销毁阶段:
componentWillUnmount (): 在此处完成组件的卸载和数据的销毁。

十一、说说你对受控组件和非受控组件的理解?应用场景?

受控组件:
表单组件的状态/数据只由state 维护 修改只能通过setState()来更新,
表单数据是由 React 组件来管理
非受控组件:
使用ref来从 DOM 节点中获取表单数据。
表单数据将交由 DOM 节点来处理

1、受控组件使用场景:
一般用在需要动态设置其初始值的情况。例如:某些form表单信息编辑时,input表单元素需要初始显示服务器返回的某个值然后进行编辑。

2、非受控组件使用场景:
一般用于无任何动态初始值信息的情况。例如:form表单创建信息时,input表单元素都没有初始值,需要用户输入的情况。

十二、说说React中setState和replaceState的区别?

setState 是修改其中的部分状态,相当于 Object. assign,只是覆盖,不会减少原来的状态;
replaceState 是完全替换原来的状态,相当于赋值,将原来的 state 替换为另一个对象,如果新状态属性减少,那么 state 中就没有这个状态了。

十三、说说react中onClick绑定后的工作原理?

React 中的 onClick 事件绑定是一种用于处理用户交互的常见方法。它的工作原理如下:
首先,在 React 组件中,开发人员定义一个 onClick 事件处理函数,该函数将在用户单击元素时被调用。
然后,使用 JSX 语法将该函数与 DOM 元素绑定。
例如,可以在一个按钮上添加 onClick 属性并将其设置为处理函数的名称。当用户单击该按钮时,浏览器会触发一个 click 事件。
React 将该事件传递给 onClick 处理函数,并调用该函数。
处理函数可以执行一些操作,例如更新组件的状态或调用其他函数。
总的来说,onClick 事件绑定的工作原理是通过将事件处理函数绑定到 DOM 元素上来实现的。当用户与该元素交互时,浏览器会触发事件并将其传递给 React,最终调用处理函数并执行相关操作。

十四、说说react diff的原理是什么?

react中diff算法主要遵循三个层级的策略:
tree层级:dom节点跨层级的操作不做优化,只会对相同层级的节点进行比较

component层级:如果是同一个类的组件,则会继续往下diff运算,如果不是一个类的组件,那么直接删除这个组件下的所有子节点,创建新的

element层级:对于比较同一层级的节点们,每个节点在对应的层级用唯一的key作为标识提供了 3 种节点操作,分别为 INSERT_MARKUP(插入)、MOVE_EXISTING (移动)和 REMOVE_NODE (删除)

十五、说说React中setState执行机制?

setState是用于更新组件状态使用的一个方法,在组件中定义一个状态,要想使得更新状态引起页面得重新渲染,就必须要使用setState来更新状态。
setState默认是同步的,但是react中会有一个变量来控制setState时直接更新(同步)还是放入到队列后续执行(异步),这个变量是根据一个方法Batced来判断setState方法是在react中执行得还是绕过react执行的。

十六、说说react的事件机制?

React的事件机制是基于合成事件(SyntheticEvent)的。合成事件是React封装的一种事件对象,它是对浏览器原生事件的封装,提供了跨浏览器的一致性,同时也有更好的性能和可靠性。

十七、什么是垂直外边距合并?说说合并后的几种情况?

垂直外边距合并:外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距。
合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
实际工作中,垂直外边距合并问题常见于第一个子元素的margin-top会顶开父元素与父元素相邻元素的间距,而且只在标准浏览器下(FirfFox、Chrome、Opera、Sarfi)产生问题,IE下反而表现良好。

合并后的几种情况:相邻块元素垂直外边距的合并
当上下相邻的两个块元素相遇时,如果上面的元素有下外边距margin-bottom,下面的元素有上外边距margin-top,则他们之间的垂直间距不是margin-bottom与margin-top之和,而是两者中的较大者。
这种现象被称为相邻块元素垂直外边距的合并(也称外边距塌陷)。

解决方案:
尽量只给一个盒子添加margin值。
嵌套块元素垂直外边距的合并
对于两个嵌套关系的块元素,如果父元素没有上内边距及边框,则父元素的上外边距会与子元素的上外边距发生合并,合并后的外边距为两者中的较大者,即使父元素的上外边距为0,也会发生合并。

解决方法:
父盒子可以加个边框
用overflow(加了这句话在浏览器中可以看到也是自动加了1px的边框)。
可以为父元素定义上内边距。

十八、 如何使用css实现一个三角形?

1.使用border绘制三角形:利用了高度为零的容器以及透明的border实现
2.使用linear-gradient绘制
3.使用conic-gradient绘制
4.transform:rotate配合overflow:hidden绘制三角形
5.使用clip-path绘制

十九、什么是强缓存和协商缓存?

强缓存:是根据返回头中的 Expires 或者 Cache-Control 两个字段来控制的,都是表示资源的缓存有效时间
协商缓存:是由服务器来确定缓存资源是否可用。 主要涉及到两对属性字段,都是成对出现的,即第一次请求的响应头带上某个字, Last-Modified 或者 Etag,则后续请求则会带上对应的请求字段 If-Modified-Since或者 If-None-Match,若响应头没有 Last-Modified 或者 Etag 字段,则请求头也不会有对应的字段。

二十、说说React jsx转换成真实DOM的过程?

使用React.createElement或JSX编写React组件 ReactDOM.render将生成好的虚拟DOM渲染到指定容器上,
react中的jsx语法会通过babel转化为 js代码,以React.createElement函数形式存在,createElement函数返回一个ReactElement函数,ReactElement函数返回一个的虚拟节点,虚拟节点中嵌套虚拟节点,就形成了虚拟DOM,最后通过ReactDOM.render方法转化为真实DOM

二十一、说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

React-redux是官方react UI绑定层,允许React组件从redux存储中读取数据,并将操作分派到存储以更新的状态。提供了connect,Provider等API,帮助我们连接react和redux,实现的逻辑会更加的严谨高效。
@reduxjs/tookit是对Redux的二次封装,开箱即用的一个高效的Redux开发工具,使得创建store,更新store

二十二、如何通过原生js实现一个节流函数和防抖函数?

防抖的实现:定义一个闭包函数,在函数内部定义个timer变量用于存储定时器,在返回的函数中判断该变量是否存在(定时器是否开始),如果存在则表示上一次的点击事件还没执行完成表示不是最后一次执行,则不进行操作;若定时器不存在则表示可以执行点击在规定的时间内不重复点击就可以实现一个防抖函数了

节流的实现:跟上面几乎差不多,只不过它需要定义一个开始点击的时间,事件执行的时间,进行计算,在规定时间内依次执行。

二十三、说说webpack中常见的loader?解决了什么问题?

style-loader 将css添加到DOM的内联样式标签style里
css-loader 允许将css文件通过require的方式引入,并返回css代码
less-loader 处理less
sass-loader 处理sass
postcss-loader 用postcss来处理CSS
autoprefixer-loader 处理CSS3属性前缀,已被弃用,建议直接使用postcss
file-loader 分发文件到output目录并返回相对路径
url-loader 和file-loader类似,但是当文件小于设定的limit时可以返回一个Data Url
html-minify-loader 压缩HTML
babel-loader 用babel来转换ES6文件到ES5

loader特性
我们一边偏向于使用,不会去在意loader的一些小细节, 这里就顺带说一下
loader 从右到左地取值(evaluate)/执行(execute)
loader 支持链式传递,链中的每个 loader 会将转换应用在已处理过的资源上
loader 也可以内联显示指定
loader 可以是同步的,也可以是异步的
loader 运行在 Node.js 中,并且能够执行任何 Node.js 能做到的操作
loader 可以通过 options 对象配置
除了常见的通过 package.json 的 main 来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用 loader 字段直接引用一个模块
loader 能够产生额外的任意文件

二十四、说说如何借助webpack来优化前端性能?

1.JS代码压缩
2.CSS代码压缩
3.Html文件代码压缩
4.文件大小压缩
5.图片压缩
6.Tree Shaking
7.代码分离
8.内联 chunk

二十五、useEffect的依赖为引用类型如何处理?

useEffect的依赖为引用数据类型,可能会导致监听不触发,原因就是监听的同一个地址的时候,对象本身地址没变,所以监听的结果就是认为数据并没有改变从而不直接调用。

解决方法
如果数据是对象的话,可以监听对象里面的值,值是基本类型,如果值改变了,那么可以监听执行
在去修改对象和数据的时候,使用深拷贝或者浅拷贝,这样地址发生改变可以监听执行
可以转换成字符串,通过JSON.stringify(),监听字符串这样的,这样改变也会执行

二十六、知道react里面的createPortal么,说说其使用场景?

react.createPortal 来制作弹窗组件,它在Modal 组件位置进行 fixed 定位,可以任意的挂载到某个dom元素上,使用后的管理更方便,但是注意需要预留html的挂载元素

Provider和connect的底层原理实现,写出其核心代码?
connect方法接受两个参数:mapStateToProps和mapDispatchToProps。它们定义了 UI 组件的业务逻辑。前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action

connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数。
一种解决方法是将state对象作为参数,传入容器组件。但是,这样做比较麻烦,尤其是容器组件可能在很深的层级,一级级将state传下去就很麻烦。
React-Redux 提供Provider组件,可以让容器组件拿到state。

二十七、说说Connect组件的原理是什么?

Connect本质上就是一个高阶函数,他是真正和store进行数据交互的组件,首先传入mapStateToProps,mapDispatchToProps,然后返回一个生产component的函数,在将真正的component作为参数传入到wrapWithconnect,这样就生产出了一个经过包裹的connect组件

二十八、说说react 中jsx语法糖的本质?

React 使用 JSX 来替代常规的JavaScript。
JSX 是按照 XML 语法规范 的 JavaScript 语法扩展。
JSX 语法的本质:并不是直接把 JSX 渲染到页面上,而是内部先转换成了 createElement 形式,再渲染的。

二十九、说说你对redux中间件的理解?常用的中间件有哪些?

中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务,衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享,功能共享的目的

常用的中间件:

Redux-thunk:用于异步操作

Redux-logger:用于日志记录

上述的中间件都需要通过applyMiddlewares进行注册
实现原理:redux中间件被放入到一个数组中,嵌套执行,然后执行store.dispatch方法,这一执行返回getState和dispatch这两个方法,然后根据dispatch进行判断,最后根据判断来决定执行

三十、说说AMD、CMD、commonJS模块化规范的区别?

AMD(异步模块定义):
AMD作为一种模块化规范,有其对应的第三方库作为具体实现,最常用的就是RequireJS。也就是说,AMD规范的应用,需要借助RequireJS第三方库才能实现。
AMD规范是非同步加载模块,允许指定回调函数。

CMD(通用模块定义)
CMD是SeaJS 在推广过程中对模块定义的规范化产出。

CommonJS
根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。所以,定义一个模块就是写一个新的js文件,但是最后要将文件的内容exports出来。
CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作

AMD和CMD区别:
对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible(尽可能的懒加载,也称为延迟加载,即在需要的时候才加载)
CMD 推崇依赖就近,AMD 推崇依赖前置
AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单

三十一、说说package.json中版本号的规则?

第一部分主版本号,表示有一个不兼容上个版本的比较大的更改
第二部分次版本号,增加了新的功能
第三部分修订版本号,修复bug
第四部分日期版本号+希腊字母版本号

三十二、说说你对koa中洋葱模型的理解?

Koa的洋葱模型是以next()函数为分割点,先由外到内执行Request的逻辑,然后再由内到外执行Response的逻辑,这里的request的逻辑,我们可以理解为是next之前的内容,response的逻辑是next函数之后的内容,也可以说每一个中间件都有两次处理时机。洋葱模型的核心原理主要是借助compose方法

三十三、说说你对webSocket的理解?

webSocket是一种网络传输协议,用于OSI模型的应用层,可以在单个ICP连接上进行全双工通信,能更好的节省服务器资源
客户端和服务器只需要一次握手,就可以创建持久性的连接,进行双向数据的传输

三十四、shouldComponentUpdate有什么作用?

shouldComponentUpdate函数是react中的一个生命周期函数,用于在更新组件前检查数据是否变化,从而决定是否重新渲染组件
作用:
(1)提升组件性能:当组件在接收到新的props和state时,可以通过 shouldComponentUpdate判断是否需要重新渲染,减少不必要的渲染
(2)允许控制:react通过此函数允许开发者控制组件是否重新渲染,能够提高开发效率,实施预期的操作

三十五、Vue中自定义指令的理解,应用场景有哪些?

指令系统是计算机硬件的语言系统,也叫机器语言,它是系统程序员看到的计算机的主要属性,因此指令系统表征了计算机的基本功能决定了机器所要求的能力
在vue中提供了一套为数据驱动试图更为方便的操作,这些操作被称为指令系统
应用场景:表单防止重复提交
图片懒加载
一键copy的功能

三十六、大文件如何做断点续传?

拿到文件,保存文件唯一性标识,切割文件,分段上传,每次上传一段,根据唯一性标识判断文件上传速度,直到文件的全部片段上传完毕

三十七、原生js如何实现上拉加载下拉刷新?

上拉加载:需要计算出当前父元素的scrollHeight在计算出当前元素的scrollTop和clientHeight通过这三个属性就可以判断出用户滑动的位置是否在最后,定义一个事件来实时判断,当用户滑动的位置到达底层后显示加载更多,后台请求服务器返回数据,与当前列表拼接则完成上拉加载操作。一般需要配合节流使用避免重复请求
下拉刷新:可以通过用户滑动当前元素的顶部位置是否达到需要刷新的位置,如果达到则进行释放操作,将元素与顶部的距离设置为0,进行刷新列表,
通过touchstart、touchmove、touchend三个事件,来判断用户得操作
当用户滑动距离大于顶部得话就设置transformy值实时修改
这两种操作都可以使用第三方库来完成。

三十八、说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?

他们之间的像素单位不同,显示程度不同,以及像素比也不一样
设备像素:不同设备的像素不一
Css像素:用于web编程,以px为后缀,是一个长度单位,相对单位和绝对单位
设备独立像素:与设备无关得逻辑像素,代表可以通过程序控制使用的虚拟像素
Dpr:设备像素比,代表设备独立像素到设备像素得转换关系
Ppi:每英寸像素,表示每英寸所含的像素点数目,就是像素密度

三十九、谈谈你对BFC的理解?

BFC及块级格式化上下文,
把一个元素变为BFC有很多种方法其中overflow:hidden最为明显。
它的目的就是为了让当前元素的排版等操作不影响外部元素。

四十、说说TCP为什么需要三次握手和四次握手?

在进行了三次握手后在服务器和客户端清晰的知道发送的对象是谁。
为了安全,在我们进行大量数据进行传输时会有恶意拦截的操作。
四次挥手是为了防止客户端是否还有未发送完的数据。
采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生错误
主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备
因为通信不可能100%可靠,而上面的三次握手已经做好了通信的准备工作,再增加握手,并不能显著提高可靠性,而且也没有必要。

四十一、react新出来两个钩子函数是什么?和删掉的will系列有什么区别?

GetDeriveStateFormProps:在第一次挂载组件时和更新state或父组件更新时执行。
GetSnapshotBeforeUpdate:在更新前可以获取到就得数据和新的数据它的返回值可以在componentDidUpdate中得第三个参数中拿到。
该周期函数在render后执行,执行之时DOM元素还没有被更新

该方法返回的一个Snapshot值,作为componentDidUpdate第三个参数传入
此方法的目的在于获取组件更新前的一些信息,比如组件的滚动位置之类的,在组件更新后可以根据这些信息恢复一些UI视觉上的状态
被删掉的几个will钩子函数是为了避免开发者滥用得,在这几个生命周期函数得前面加上UNSAFE_前缀还是可以使用的,这几个钩子有它们得好处也有弊端,并且在react以后的版本可能会被废除

四十二、最少说出三种前端清除浮动的方法?

使用带clear属性的空元素
使用css的overflow属性
使用css的:after伪元素

四十三、React render方法的原理,在什么时候会触发?

一、原理
在类组件和函数组件中,render函数的形式是不同的。
在类组件中render函数指的就是render方法;而在函数组件中,指的就是整个函数组件。
二、触发时机
render的执行时机主要分成了两部分:
类组件调用 setState 修改状态
函数组件通过useState hook修改状态

四十四、React性能优化的手段有哪些?

避免使用内联函数
使用immutable
懒加载组件
事件绑定方法
服务器渲染

四十五、说说你对git rebase 和git merge的理解?区别?

rebase会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交,主要的好处是历史记录更加清晰,是在原有提交的基础上将差异内容反映进去,消除了 git merge所需的不必要的合并提交

merge和rebasea都是合并历史记录,但是各自特性不同:merge通过merge合并分支会新增一个merge commit,然后将两个分支的历史联系起来其实是一种非破坏性的操作,对现有分支不会以任何方式被更改,但是会导致历史记录相对复杂rebaserebase会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交主要的好处是历史记录更加清晰,是在原有提交的基础上将差异内容反映进去,消除了 git merge所需的不必要的合并提交

四十六、在使用redux过程中,如何防止定义的action-type的常量重复?

Es6引入了一种新的原始数据类型Symbol,表示独一无二的值
Symbol是一个原始类型的值,不是对象symbol函数可以接受一个字符串作为参数,表示对symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分

四十七、调和阶段setState干了什么?

当调用setState时,将传递给setState的对象合并到组件的当前状态,这一启动称为和解的过程,

四十八、props和state相同点和不同点?render方法在哪些情况下会执行?

props:
props是一个从外部传进组件的参数,由于React具有单向数据流的特性,所以他的主要作用是从父组件向子组件中传递数据,它是不可改变的,如果想要改变它,只能通过外部组件传入新的props来重新渲染子组件,否则子组件的props和展示形式不会改变,props除了可以传字符串,数字,还可以传递对象,数组甚至是回调函数
state:
state主要作用是用于组件保存,控制及修改自己的状态,它只能在constructor中初始化,state是可以被改变的,state放改动的一些属性,比如点击选中,再点击取消,类似这种属性就放入带state中,注意:没有state的叫做无状态组件,多用props少用state,多写无状态组件,注意:修改state的值时,必须通过调用setState方法,当我们调用this.setState方法时,React会更新组件的数据状态,并且重新调用render方法

不同点:
1.props不可以在组件内部修改,但state可以在组件内部修改
2.可以从父组件修改自组件的props,而不能从父组件修改自组件的state

相同点:
1.props和state都是导出HTML的原始数据。
2.props和state都是确定性的,如果我们写的组件为同一props和state的组合3.生成了不同的输出,那木我们肯定在哪里做错了
4.props和state都会触发渲染更新
5.props和state都是纯JS对象(用typeof来判断,结果都是object)
6.可以从父组件得到初始值props和state的初始值

触发时机:
类组件调用用setState修改状态,从而执行render
函数组件通过useState的hook修改状态,函数通过useState这种形式更新数据,当数组的值不在发生变化就不会触发render

四十九、shouldComponentUpdate有什么作用?

shouldComponentUpdate是React中的一个生命周期方法,它的作用是控制组件是否需要重新渲染。
当组件的props或state发生变化时,React会调用shouldComponentUpdate方法,该方法默认返回true,表示组件需要重新渲染。但是,在某些情况下,组件并不需要重新渲染,这时可以在shouldComponentUpdate方法中进行一些判断,返回false表示组件不需要重新渲染,从而提高程序的性能和效率。
shouldComponentUpdate方法可以接收两个参数:nextProps和nextState,分别表示组件即将接收到的props和state。在shouldComponentUpdate方法中,开发者可以根据当前的props和state以及即将接收到的nextProps和nextState进行一些比较和判断,以决定是否需要重新渲染组件。

五十、说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关系?

虚拟dom:
虚拟DOM就是一个JS对象,通过对象的方式来表示DOM结构,通过事务处理机制,将多次DOM修改的结果一次性更新到页面上,从而有效的减少页面渲染次数,减少修改DOM重绘重排的时间,提高渲染性能

diff和key之间关系:
key是React用于追踪列表中哪些元素被修改、被添加、被移除的辅助标识。
在开发中,我们要保证每个元素的key在其同级的元素中具有唯一性。
diff算法中会借助key来判断该元素是新创建的还是被移动而来的元素,从而减少不必要的渲染

当同一层级的某个节点添加了对于其他同级节点唯一的key属性,当它在当前层级的位置发生了变化后。
react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作。这无疑大大提高了React性能和渲染效率

五十一、react新出来两个钩子函数是什么?和删掉的will系列有什么区别?

React类组件中新出来的两个生命周期函数是getDerivedStateFromProps和getSnapshotBeforeUpdate。

区别在于:

在组件更新阶段,getDerivedStateFromProps是在render方法之前调用,用于更新组件的state状态。而getSnapshotBeforeUpdate是在组件的DOM更新之前调用,可以获取到组件更新前的状态。
getDerivedStateFromProps钩子函数是一个静态方法,不可以访问组件实例的this对象,只能通过传入的参数获取当前组件的状态和属性。而getSnapshotBeforeUpdate方法可以访问组件实例的this对象。
will系列的生命周期函数已经被标记为过时,不建议再使用,而getDerivedStateFromProps和getSnapshotBeforeUpdate是React16.3以后新增的生命周期函数,可以在类组件中使用。

总的来说,getDerivedStateFromProps和getSnapshotBeforeUpdate的使用场景比will系列更加明确和安全,但需要注意使用时的细节。

五十二、React的props.children使用map函数来遍历会收到异常显示,为什么?应该 如何遍历?

在react 中 props.children 不一定是数组
有三种可能 :
1.当前组件没有子节点数据类型就是undefined,
2.有一个子节点数据类型就是object 。
3 .有多个子节点的时候才会是array ,只有在多个节点的时候才可以直接调用map方法,react提供了一个react.children.map()方法,可以安全遍历子节点对象。

五十三、谈谈你对immutable.js的理解?

immutable不可改变的,在计算机中,即指一旦创建,就不能再被更改的数据
对immutable对象的任何修改或添加删除操作都会返回一个新的immutable对象
immutable实现原理是Persistent Data Structure (持久化数据结构):用一种数据结构来保存数据 当数据被修改时,会返回一个对象,但是新的对象会尽可能的利用之前的数据结构而不会对内存造成浪费,也就是使用旧数据创建新数据时,要保证旧数据同时可用并且不变,同时为了避免deepCopy把所有节点都复制一遍带来的性能损耗,immutable使用 Structural Sharing(数据共享)
如果对象树中一个及诶大那发生变化,只修改这个节点和受它影响的父节点,其他节点则进行共享

五十四、redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的实现原理是什么?

因为它使用了redux-thunk或者redux-thunk这两个异步操作的中间件,
原理是在派发action时,要执行dispatch进行拦截,先不更新store中的数据,等返回数据
将所有的中间件放入到一个数组中,进行嵌套,最后将执行store.dispatch方法,这一执行操作,会返回两个方法,一个是getState方法,另一个是dispatch方法,然后根据返回的这两个方法,进行if判断,再根据这个判断,执行相对于的操作

五十五、redux中同步action与异步action最大的区别是什么?

同步action:执行了dispatch函数之后,对应的reducer纯函数立即得到执行,reducer执行完了之后,state立即就改变了,此时用store.getState函数,取到的是最新的state值;

异步action:原则上redux并没有提供异步action的处理方案,异步的action需要依赖第三方的中间件解决(如redux-thunk),dispatch了一个异步action(本质上是dispatch的一个函数)之后,目标state并不会立即响应,而是要看异步函数内部的逻辑,来决定state什么时候响应.

五十六、redux-saga和redux-thunk的区别与使用场景?

redux-saga:
redux-saga在store的index文件中创建saga中间件连接到store,saga中间件可以监控派发action,如果有action.type值与监控的变量一致,则执行该函数的内容,在这个函数中也可以再派发一个新的action

redux-thunk:
redux-thunk相当于是基于store的升级,一般情况,我们传给store的action是一个对象,但是通过redux-thunk中间件,我们可以把部分的业务逻辑(异步请求)等放在action中进行处理。当store接收到函数类型的action,redux-thunk会执行该函数,并传入参数dispatch,当函数内部的逻辑执行完成后,会再次派发一个action继续向下执行。

区别:
redux-thunk和redux-saga中间件相当于对store的升级,thunk通过执行action中的函数实现业务逻辑,没有扩展API;saga通过定义saga函数进行监控,同时提供一些常用的API

应用场景:
redux-thunk:
dispatch一个action之后,到达reducer之前,进行一些额外的操作,就需要用到middleware。你可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
  换言之,中间件都是对store.dispatch()的增强。redux-thunk就是用来异步操作,比如接口请求等。

redux-saga:
redux-saga是一个用于管理redux应用异步操作的中间件,redux-saga通过创建sagas将所有异步操作逻辑收集在一个地方集中处理,可以用来代替redux-thunk中间件

五十七、CDN的特点及意义?

CDN的作用:实际上,内容分发布网络(CDN)是一种新型的网络构建方式,它是为能在传统的IP网发布宽带丰富媒体而特别优化的网络覆盖层;而从广义的角度,CDN代表了一种基于质量与秩序的网络服务模式

CDN 是构建在数据网络上的一种分布式的内容分发网。 CDN 的作用是采用流媒体服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提升系统支持的并发流数目,减少或避免单点失效带来的不良影响

五十八、为什么for循环比forEach性能高?

一、for()循环?
for循环就是通过下标,对循环中的代码反复执行,功能强大,可以通过index取得元素。处理比较复杂的处理的时候比较方便
二、forEach()循环
forEach()循环方法用于调用数组的每个元素,并将元素传递给回调函数。forEach有的也叫做增强for循环,forEach其实是for循环的一个特殊简化版。forEach循环对于空的数组是不会执行回调函数的

如何进行选择?
foreach相对于for循环,代码减少了,但是foreach依赖于IEnumerable。
在运行的时候效率比for循环低。当然,在处理不确定循环次数的循环,或者循环次数需要计算的情况下。使用foreach比较方便,而且foreach的代码经过编译系统的代码优化以后,for循环使用更加灵活。

五十九、React render方法的原理,在什么时候会触发?

Render方法在类组件和函数组件中表示的是不一样的
Render方法在类组件中表示的是一个方法,而render方法在函数组件中表示的是整个函数组件
类组件是在调用setState中触发,函数组件是在调用useState hook时触发

六十、![] == ![],![] == [],结果是什么?为什么?

结果都为true
!的字符串,!的null,!的underfinde都是为true,其余的都是false
!的优先级比==的高
根据上述规定,可以得出![]为false
所以![] == ![]
在经行比较时【】会被转化为false的
所以![] == []

六十一、什么是闭包,应用场景是什么?

参考回答: 闭包是指有权访问另外一个函数作用域中的变量的函数。 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。闭包就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数并不在栈上分配,而是在堆上分配。当在一个函数内定义另外一个函数就会产生闭包。
应用场景:例如私有变量,使用定时器,手动写入防抖函数和节流函数

六十二、谈谈你是如何做移动端适配的?

1.px + viewport适配
2.rem布局
。CSS3媒体查询适配
。基于设计图的rem布局
。基于屏幕百分比的rem布局
。小程序的rpx布局
3.vw布局
。通过媒体查询的方式即CSS3的meida queries
。以天猫首页为代表的flex弹性布局
。以淘宝首页为代表的rem+viewport缩放
。rem方式

六十三、移动端1像素的解决方案?

1.媒体查询利用设备像素比缩放,设置小小数像素
2.设置border-image方案
3.background-image渐变实现
4.box-shadow
5.viewport+rem
6.transform: scale(0.5) 方案 - 推荐: 很灵活
7、媒体查询 + transfrom 对方案1的优化

六十四、弹性盒中的缩放机制是怎样的?

弹性盒中的项目设置flex-grow属性定义项目的放大比例,默认值为0,值越大,放大越厉害,且不支持负值;
而flex-shrink属性定义项目的缩小比例,默认值为1,数值越大,缩小越厉害,同样不支持负值;

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间。他的默认值为auto,也就是项目的本来大小。

六十五、说说React生命周期中有哪些坑?如何避免?


getDerivedStateFromProps 容易编写反模式代码,使受控组件和非受控组件区分模糊

componentWillMount 在 React 中已被标记弃用,不推荐使用,主要的原因是因为新的异步架构会导致它被多次调用,所以网络请求以及事件绑定应该放到 componentDidMount 中

componentWillReceiveProps 同样也被标记弃用,被 getDerivedStateFromProps 所取代,主要原因是性能问题。

shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要触发新的渲染。主要用于性能优化。

componentWillUpdate 同样是由于新的异步渲染机制,而被标记废弃,不推荐使用,原先的逻辑可结合 getSnapshotBeforeUpdate 与 componentDidUpdate 改造使用。

如果在 componentWillUnmount 函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug。

如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所以一定要添加。

避免生命周期中的坑需要做好两件事:
不在恰当的时候调用了不该调用的代码;

在需要调用时,不要忘了调用。

六十六、 说说Real diff算法是怎么运作的?

主要分为3层:tree层、component层、element层
(1)、tree层:tree层对DOM节点的跨层级移动的操作忽略不计,只对相同层级的DOM节点进行比较(即同一个父节点下的所有子节点),一旦发现节点不存在,直接删除掉该节点以及之下的所有子节点

(2)、component层:
遇到同一类型的组件遵循 tree diff,进行层级对比
遇到不同类型的组件,直接将这个不同的组件判断为脏组件,并替换该组件和之下所有的子节点
在同一类型的两个组件中,当知道这个组件的虚拟dom没有任何变化,就可以手动使用shouldComponentUpdate()来判断组件是否需要进行diff,进一步的提升了diff效率和性能
(3)、element层:
对同一层级的元素节点进行比较,有三种情况:

面对全新的节点时,执行插入操作
面对多余的节点时,执行删除操作
面对换位的节点时,执行移动操作

六十七、调和阶段setState干了什么?

(1)代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。
(2)经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
(3)在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
(4)在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

六十八、 说说redux的实现原理是什么,写出核心代码?

redux就是一个实现上述集中管理的容器,遵循三大基本原则
单一数据源
state 是只读的
使用纯函数来执行修改

核心代码:
createStore可以帮助创建 store
store.dispatch 帮助派发 action , action 会传递给 store
store.getState 这个方法可以帮助获取 store 里边所有的数据内容
store.subscrible 方法订阅 store 的改变,只要 store 发生改变, store.subscrible 这个函数接收的这个回调函数就会被执行

const redux = require(‘redux’);

const initialState = {
counter: 0
}

// 创建reducer
const reducer = (state = initialState, action) => {
switch (action.type) {
case “INCREMENT”:
return {…state, counter: state.counter + 1};
case “DECREMENT”:
return {…state, counter: state.counter - 1};
case “ADD_NUMBER”:
return {…state, counter: state.counter + action.number}
default:
return state;
}
}

// 根据reducer创建store
const store = redux.createStore(reducer);

store.subscribe(() => {
console.log(store.getState());
})

// 修改store中的state
store.dispatch({
type: “INCREMENT”
})
// console.log(store.getState());

store.dispatch({
type: “DECREMENT”
})
// console.log(store.getState());

store.dispatch({
type: “ADD_NUMBER”,
number: 5
})
// console.log(store.getState());

六十九、React合成事件的原理?

React 合成事件(SyntheticEvent)是 React 模拟原生 DOM 事件所有能力的一个事件对象,即浏览器原生事件的跨浏览器包装器。它根据 W3C 规范 来定义合成事件,兼容所有浏览器,拥有与浏览器原生事件相同的接口。

将事件绑定在document - v16/容器元素 - v17统一管理,防止很多事件直接绑定在原生的dom元素上。造成一些不可控的情况
React 想实现一个全浏览器的框架, 为了实现这种目标就需要提供全浏览器一致性的事件系统,以此抹平不同浏览器的差异。

七十、为什么react元素有一个$$type属性?

从设计上来说,React 元素是一个普通的对象
但是,如果服务器侧有一个允许用户存储任意JSON对象的漏洞,而客户端代码期待一个字符串,在这种情况下,React 0.13很容易受到XSS攻击。这种攻击取决于现有的服务器漏洞
在React 0.14版本,它的修复方法是对每一个React元素使用Symbol来进行标记
React将检查元素的 t y p e o f 属性,如果 typeof属性,如果 typeof属性,如果typeof属性丢失或无效,将拒绝处理该元素

七十一、说说Connect组件的原理是什么?

connect是连接React组件与Redux store
在原本应用组件上包裹一层,使原来整个应用成为Provider的子组件
接受Redux的store作为props,通过context对象传递给子孙组件上的connect

七十二、说说你对fiber架构的理解?解决了什么问题?

React Fiber 是 Facebook 花费两年余时间对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现

在react中,主要做了以下的操作:

为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务

增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行

dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行

从架构角度来看,Fiber 是对 React核心算法(即调和过程)的重写

七十三、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

中间件(Middleware)是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的

有很多优秀的redux中间件,如:

redux-thunk:用于异步操作

redux-logger:用于日志记录

实现原理
所有中间件被放进了一个数组chain,然后嵌套执行,最后执行store.dispatch。可以看到,中间件内部(middlewareAPI)可以拿到getState和dispatch这两个方法

七十四、说说你对react的理解?有哪些特性?

React,用于构建用户界面的 JavaScript 库,只提供了 UI 层面的解决方案

特性

遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效

使用虚拟 DOM 来有效地操作 DOM,遵循从高阶组件到低阶组件的单向数据流

帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面

七十五、说说Real DOM和Virtual DOM的区别?优缺点?

Real DOM,真实DOM, 意思为文档对象模型,是一个结构化文本的抽象,在页面渲染出的每一个结点都是一个真实DOM结构

Virtual Dom,本质上是以 JavaScript 对象形式存在的对 DOM 的描述

区别:
虚拟DOM不会进行排版与重绘操作,而真实DOM会频繁重排与重绘

虚拟DOM的总损耗是“虚拟DOM增删改+真实DOM差异增删改+排版与重绘”,真实DOM的总损耗是“真实DOM完全增删改+排版与重绘”

优缺点
真实DOM的优势:

易用

缺点:

效率低,解析速度慢,内存占用量过高

性能差:频繁操作真实DOM,易于导致重绘与回流

使用虚拟DOM的优势如下:

简单方便:如果使用手动操作真实DOM来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难

性能方面:使用Virtual DOM,能够有效避免真实DOM数频繁更新,减少多次引起重绘与回流,提高性能

跨平台:React借助虚拟DOM, 带来了跨平台的能力,一套代码多端运行

缺点:

在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化

首次渲染大量DOM时,由于多了一层虚拟DOM的计算,速度比正常稍慢

七十六、说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?

一共分为三个阶段:

创建阶段
更新阶段
卸载阶段

创建阶段:

constructor:实例过程中自动调用的方法,在方法内部通过super关键字获取来自父组件的props
在该方法中,通常的操作为初始化state状态或者在this上挂载方法
getDerivedStateFromProps:该方法是新增的生命周期方法,是一个静态的方法,因此不能访问到组件的实例
执行时机:组件创建和更新阶段,不论是props变化还是state变化,也会调用
在每次render方法前调用,第一个参数为即将更新的props,第二个参数为上一个状态的state,可以比较props 和 state来加一些限制条件,防止无用的state更新
该方法需要返回一个新的对象作为新的state或者返回null表示state状态不需要更新
render:类组件必须实现的方法,用于渲染DOM结构,可以访问组件state与prop属性
注意: 不要在 render 里面 setState, 否则会触发死循环导致内存崩溃
componentDidMount:组件挂载到真实DOM节点后执行,其在render方法之后执行
更新阶段:

getDerivedStateFromProps:同上
shouldComponentUpdate:用于告知组件本身基于当前的props和state是否需要重新渲染组件,默认情况返回true
执行时机:到新的props或者state时都会调用,通过返回true或者false告知组件更新与否
一般情况,不建议在该周期方法中进行深层比较,会影响效率
同时也不能调用setState,否则会导致无限循环调用更新
render:同上
getSnapshotBeforeUpdate:该周期函数在render后执行,执行之时DOM元素还没有被更新
该方法返回的一个Snapshot值,作为componentDidUpdate第三个参数传入

componentDidUpdate:执行时机:组件更新结束后触发
在该方法中,可以根据前后的props和state的变化做相应的操作,如获取数据,修改DOM样式等
卸载阶段:

componentWillUnmount:此方法用于组件卸载前,清理一些注册是监听事件,或者取消订阅的网络请求等
一旦一个组件实例被卸载,其不会被再次挂载,而只可能是被重新创建

七十七、说说React中setState执行机制?

setState是同步执行的
setState是同步执行的,但是state并不一定会同步更新
setState在React生命周期和合成事件中批量覆盖执行
在React的生命周期钩子和合成事件中,多次执行setState,会批量执行

具体表现为,多次同步执行的setState,会进行合并,类似于Object.assign,相同的key,后面的会覆盖前面的

当遇到多个setState调用时候,会提取单次传递setState的对象,把他们合并在一起形成一个新的
单一对象,并用这个单一的对象去做setState的事情,就像Object.assign的对象合并,后一个
key值会覆盖前面的key值

setState在原生事件,setTimeout,setInterval,Promise等异步操作中,state会同步更新
异步操作中setState,即使在React的钩子或合成事件中,state都不会批量更新,而是会同步更新,
多次连续操作setState,每次都会re-render,state会同步更新

七十八、说说react的事件机制?

React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等在React中这套事件机制被称之为合成事件
合成事件是 React模拟原生 DOM事件所有能力的一个事件对象,即浏览器原生事件的跨浏览器包装器
总结
React事件机制总结如下:

React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的
DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)
React 自身实现了一套事件冒泡机制,所以这也就是为什么我们 event.stopPropagation()无效的原因。
React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callback
React 有一套自己的合成事件 SyntheticEvent

七十九、 React组件之间如何通信?

1、父组件向子组件通讯:父组件可以向子组件传入props的方式,向子组件进行通讯。
2、子组件向父组件通讯:props+回调的方式,父组件向子组
件传递props进行通讯,此props为作用域为父组件自身的函
数,子组件调用该函数,将子组件想要传递的信息,作为参
数,传递到⽗组件的作⽤域中。
3、兄弟组件通信:找到这两个兄弟节点共同的⽗节点,结合上
⾯两种⽅式由⽗节点转发信息进⾏通信。
4、跨层级通讯:Context 设计⽬的是为了共享那些对于⼀个
组件树⽽⾔是“全局”的数据,例如当前认证的⽤户、主题
或⾸选语⾔,对于跨越多层的全局数据通过 Context 通信再
适合不过。
5、发布订阅者模式:发布者发布事件,订阅者监听事件并做出
反应,我们可以通过引⼊event模块进⾏通信。
6、全局状态管理工具:借助Redux或者Mobx等全局状态管理
⼯具进⾏通信,这种⼯具会维护⼀个全局状态中⼼Store,并根
据不同的事件产⽣新的状态。

八十、 说说你对受控组件和非受控组件的理解?应用场景?

1.受控组件的概念:
在React中,可变状态通常保存在组件的状态属性中,并且只能使用setState()进行更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,成为受控组件

2.非受控组件:
非受控组件指的是表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示的最新值

受控组件与非受控组件的区别
1.受控组件
a.受控组件依赖于状态(它是通过setState来更新表单数据,可以对表单进行操作)

b.受控组件的修改会实时映射到状态值上,此时可以对输入的内容进行校验

c.受控组件只用继承React.Component才会有状态(这个区别自己还是一知半解)

d.受控组件必须要在表单上使用onChange事件来绑定对应的事件(表单元素通过onChange发生改变时触发setState更新状态)
    
2.非受控组件
a.非受控组件不受状态的控制

b.非受控组件获取数据就相当于操作DOM(通过ref来获取数据)

c.非受控组件可以很容易与第三方组件结合,更容易同时集成React和非React代码

应用场景
1、受控组件使用场景:
一般用在需要动态设置其初始值的情况。例如:某些form表单信息编辑时,input表单元素需要初始显示服务器返回的某个值然后进行编辑。

2、非受控组件使用场景:
一般用于无任何动态初始值信息的情况。例如:form表单创建信息时,input表单元素都没有初始值,需要用户输入的情况。

八十一、ts中any类型与unkown类型

any可以赋值给其他的类型,unkown不可以,除非
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值