1.说说你对react的理解?有哪些特性?
React,用于构建用户界面的 JavaScript 库,只提供了 UI 层面的解决方案
遵循组件设计模式、声明式编程范式和函数式编程概念,以使前端应用程序更高效
使用虚拟 DOM 来有效地操作 DOM,遵循从高阶组件到低阶组件的单向数据流
帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面
react 类组件使用一个名为 render() 的方法或者函数组件return,接收输入的数据并返回需要展示的内容
React 特性有很多,如:
JSX 语法
单向数据绑定
虚拟 DOM
声明式编程
Component
2.说说Real DOM和VirtualDOM的区别?优缺点?
Real DOM,真实 DOM,意思为文档对象模型,是一个结构化文本的抽象,在页面渲染出的每一个结点都是一个真实 DOM 结构
Virtual Dom,本质上是以 JavaScript 对象形式存在的对 DOM 的描述
创建虚拟 DOM 目的就是为了更好将虚拟的节点渲染到页面视图中,虚拟 DOM 对象的节点与真实 DOM 的属性一一照应
两者的区别如下:
虚拟 DOM 不会进行排版与重绘操作,而真实 DOM 会频繁重排与重绘
虚拟 DOM 的总损耗是“虚拟 DOM 增删改+真实 DOM 差异增删改+排版与重绘”,真实 DOM 的总损耗是“真实 DOM 完全增删改+排版与重绘
两者优势
真实 DOM 的优势:
易用
缺点:
效率低,解析速度慢,内存占用量过高
性能差:频繁操作真实 DOM,易于导致重绘与回流
使用虚拟 DOM 的优势如下:
简单方便:如果使用手动操作真实 DOM 来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难
性能方面:使用 Virtual DOM,能够有效避免真实 DOM 数频繁更新,减少多次引起重绘与回流,提高性能
跨平台:React 借助虚拟 DOM,带来了跨平台的能力,一套代码多端运行
缺点:
在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化
首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,速度比正常稍慢
3.说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?
可以分成三个阶段:
创建阶段
更新阶段
卸载阶段
创建阶段
创建阶段主要分成了以下几个生命周期方法:
constructor
getDerivedStateFromProps
render
componentDidMoun
更新阶段
该阶段的函数主要为如下方法:
getDerivedStateFromProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
componentDidUpdate
卸载阶段
componentWillUnmount
4.说说React中setState执行机制?
一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state
当需要修改里面的值的状态需要通过调用setState来改变,从而达到更新组件内部数据的作用
在使用setState更新数据的时候,setState的更新类型分成:
异步更新
同步更新
小结
在组件生命周期或React合成事件中,setState是异步
在setTimeout或者原生dom事件中,setState是同步
5.说说react的事件机制?
React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等
在React中这套事件机制被称之为合成事件
合成事件
合成事件是 React模拟原生 DOM事件所有能力的一个事件对象,即浏览器原生事件的跨浏览器包装器
根据 W3C规范来定义合成事件,兼容所有浏览器,拥有与浏览器原生事件相同的接口
总结
React事件机制总结如下:
React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)
React 自身实现了一套事件冒泡机制,所以这也就是为什么我们 event.stopPropagation()无效的原因。
React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callback
React 有一套自己的合成事件 SyntheticEvent
6.React组件之间如何通信?
7.说说你对受控组件和非受控组件的理解?应用场景?
参考文献
8.说说你对fiber架构的理解?解决了什么问题?
什么是fiber:react16以后的一个虚拟dom思想
为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务
增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行
dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行
9.说说react diff的原理是什么?
diff算法可以看作是一种对比算法,对比的对象是新旧虚拟Dom。顾名思义,diff算法可以找到新旧虚拟Dom之间的差异,但diff算法中其实并不是只有对比虚拟Dom,还有根据对比后的结果更新真实Dom。
合理利用key可以有效减少真实Dom的变动,从而减少页面重绘和回流的频率,进而提高页面更新的效率
10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
中间件:它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的
常用的中间件
有很多优秀的redux中间件,这里我们例举两个:
redux-thunk:用于异步操作
redux-logger:用于日志记录
上述的中间件都需要通过applyMiddlewares进行注册,作用是将所有的中间件组成一个数组,依次执行然后作为第二个参数传入到createStore中
redux-thunk中间件会判断你当前传进来的数据类型,如果是一个函数,将会给函数传入参数值(dispatch,getState)
dispatch函数用于我们之后再次派发action
getState函数考虑到我们之后的一些操作需要依赖原来的状态,用于让我们可以获取之前的一些状态
11.如何使用css实现一个三角形?
div{
width: 0px;
height: 0px;
border-width: 30px;
border-style: solid;
border-color: red transparent transparent transparent;
overflow: hidden;
font-size: 0;
line-height: 0;
12.什么是强缓存和协商缓存?
什么是强缓存
服务器通过设置http中hdader的Expires和cache-control字段告诉浏览器换存的有效期。这种方法会有一个固定时间,所带来的问题是如果服务器数据进行了更新,但是还没有到强缓存的过期时间,则数据无法更新
什么是协商缓存
简单的说,协商缓存就是通过服务器来判断缓存是否可用。
13.说说React jsx转换成真实DOM的过程?
使用React.createElement或JSX编写React组件,实际上所有的 JSX 代码最后都会转换成React.createElement(...) ,Babel帮助我们完成了这个转换的过程。
createElement函数对key和ref等特殊的props进行处理,并获取defaultProps对默认props进行赋值,并且对传入的孩子节点进行处理,最终构造成一个虚拟DOM对象
ReactDOM.render将生成好的虚拟DOM渲染到指定容器上,其中采用了批处理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实DOM
14.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?
react-redux 是的官方 React UI 绑定层,允许您的 React 组件从 Redux 存储中读取数据,并将操作分派到存储以更新状态。
@reduxjs/toolkit
@reduxjs/toolkit 是对 Redux 的二次封装,开箱即用可的一个高效的 Redux 开发工具集,使得创建store、更新store
15.React render方法的原理,在什么时候会触发?
一、原理
在类组件和函数组件中,render函数的形式是不同的。
在类组件中render函数指的就是render方法;而在函数组件中,指的就是整个函数组件。
二、触发时机
render的执行时机主要分成了两部分:
类组件调用 setState 修改状态
函数组件通过useState hook修改状态
16.React性能优化的手段有哪些?
使用 shouldComponentUpdate 避免不需要的渲染
将 props 设置为数组或对象
将函数的绑定移动到构造函数内
使用 immutable 不可变数据
给子组件设置一个唯一的 key,因为在 diff 算法中,会用 key 作为唯一标识优化渲染
17.如何通过原生js实现一个节流函数和防抖函数?
18.说说webpack中常见的loader?解决了什么问题?
常见的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文件到ES
oader 用于对模块的"源代码"进行转换,在 import 或"加载"模块时预处理文件
解决的一些问题
可以通过 loader 的预处理函数,为 JavaScript 生态系统提供更多能力。用户现在可以更加灵活地引入细粒度逻辑,例如:压缩、打包、语言翻译和更多其他特性
19.说说如何借助webpack来优化前端性能?
1、压缩代码
2、利用CDN加速
3、Tree shaking:将代码中永远不会⾛到的⽚段删除掉
4、按需加载
5、提取公共第三⽅库
20.说说javascript内存泄漏的几种情况?
意外的全局变量
定时器也常会造成内存泄露
没有清理对DOM元素的引用同样造成内存泄露
过度使用闭包函数
包括使用事件监听addEventListener监听的时候,在不监听的情况下使用removeEventListener取消对事件监听