[2021] 30道中高级高频react面试题总结

6,131 阅读11分钟

前言

本文是自己最近面试前端岗位,被问及的react面试题,回家之后对 react面试题进行整理汇总,希望读者读完本文,对react面试题可以加深印象,也能对自己的 react掌握程度有一定的认识,自己复习可以查漏补缺,不足之处可以弥补,如有错误之处,欢迎批评指教!感谢拜读!

1,react和vue区别

a, vue是双向数据绑定 react是单向数据流
b, 在 Vue 中我们组合不同功能的方式是通过 mixin,而在React中我们通过 HoC (高阶组件)
c, 组件传值不同 Vue中子组件向父组件传递消息有两种方式:事件和回调函数,而且Vue更倾向于使用事件。
但是在 React 中我们都是使用回调函数的
d, React 是通过JSX渲染模板  而Vue是通过一种拓展的HTML语法进行渲染
e, vue有v-model语法糖等

2,react无状态组件和class类组件的区别

1,直观区别,函数组件代码量较少,相比类组件更加简洁
2,函数组件看似只是一个返回react元素的函数,其实体现的是无状态组件的思想,函数组件中没有this,
没有state,也没有生命周期,这就决定了函数组件都是展示性组件,接收props,渲染dom,而不关注其他逻辑
3,因为函数组件不需要考虑组件状态和组件生命周期方法中的各种比较校验,所以有很大的性能提升空间

3,模仿vue中v-model指令,react实现类似双向绑定

通过onchange事件监听input的value值,再通过this.setState改变显示出来

4,react的高阶组件用法以及作用

高阶组件就是接受一个组件作为参数并返回一个新组件(功能增强的组件)的函数。这里需要注意高阶组件是一个函数,并不是组件。
将几个功能相似的组件里面的方法和react特性(如生命周期里面的副作用)提取到HOC中,然后向HOC传入需要封装的组件。最后将公用的方法传给组件。

5,React生命周期

目前React 16.8 +的生命周期分为三个阶段,分别是挂载阶段、更新阶段、卸载阶段。

挂载阶段:

· constructor: 构造函数,最先被执行,我们通常在构造函数里初始化state对象或者给自定义方法绑定this

· getDerivedStateFromProps: static getDerivedStateFromProps(nextProps, prevState),这是个静态方法,当我们接收到新的属性想去修改我们state,可以使用getDerivedStateFromProps

· render: render函数是纯函数,只返回需要渲染的东西,不应该包含其它的业务逻辑,可以返回原生的DOM、React组件、Fragment、Portals、字符串和数字、Booleannull等内容

· componentDidMount: 组件装载之后调用,此时我们可以获取到DOM节点并操作,比如对canvas,svg的操作,服务器请求,订阅都可以写在这个里面,但是记得在componentWillUnmount中取消订阅

更新阶段

· getDerivedStateFromProps: 此方法在更新个挂载阶段都可能会调用

· shouldComponentUpdate: shouldComponentUpdate(nextProps, nextState),有两个参数nextProps和nextState,表示新的属性和变化之后的state,返回一个布尔值,true表示会触发重新渲染,false表示不会触发重新渲染,默认返回true,我们通常利用此生命周期来优化React程序性能

· render: 更新阶段也会触发此生命周期

· getSnapshotBeforeUpdate: getSnapshotBeforeUpdate(prevProps, prevState),这个方法在render之后,componentDidUpdate之前调用,有两个参数prevProps和prevState,表示之前的属性和之前的state,这个函数有一个返回值,会作为第三个参数传给componentDidUpdate,如果你不想要返回值,可以返回null,此生命周期必须与componentDidUpdate搭配使用

· componentDidUpdate: componentDidUpdate(prevProps, prevState, snapshot),该方法在getSnapshotBeforeUpdate方法之后被调用,有三个参数prevProps,prevState,snapshot,表示之前的props,之前的state,和snapshot。第三个参数是getSnapshotBeforeUpdate返回的,如果触发某些回调函数时需要用到 DOM 元素的状态,则将对比或计算的过程迁移至 getSnapshotBeforeUpdate,然后在 componentDidUpdate 中统一触发回调或更新状态。

卸载阶段

componentWillUnmount: 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除定时器,取消网络请求或清除在 componentDidMount() 中创建的订阅,清理无效的DOM元素等垃圾清理工作。

6,React中setState做了什么

setState不会立刻改变react组件中state的值,setState通过触发一次组件的更新来引发重汇,多次setState函数调用产生的效果会合并

调用 setState时,React会做的第一件事情是将传递给 setState的对象合并到组件的当前状态。这将启动一个称为和解(reconciliation)的过程。和解(reconciliation)的最终目标是以最有效的方式,根据这个新的状态来更新UI。 为此,React将构建一个新的 React元素树(您可以将其视为 UI 的对象表示)。

一旦有了这个树,为了弄清 UI 如何响应新的状态而改变,React 会将这个新树与上一个元素树相比较

7,React组件传值有哪些方式

父传子:props   子传父:通过在父组件引入的子组件中传递一个函数并传参数,子组件去触发这个函数更改参数完成数据更新

跨多层组件传值:通过context api完成

8,React中什么是纯函数

一个函数的返回结果只依赖其参数,并且执行过程中没有副作用。

9,React路由实现原理

react-router 的依赖库history

1、BrowserHistory:用于支持 HTML5 历史记录 API 的现代 Web 浏览器(请参阅跨浏览器兼容性) \
2、HashHistory:用于旧版Web浏览器\
3、MemoryHistory:用作参考实现,也可用于非 DOM 环境,如 React Native 或测试

BrowserHistory:pushState、replaceState
HashHistory:location.hash、location.replace

10,Redux有哪些参数分别有什么用

store: 保存数据的地方
State: 状态管理器
Action: 提交state的唯一方法
Reducer:返回新的state纯函数

11,redux-thunk,redux-saga有什么作用

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

· 查询与责任分离,保证了action的纯洁性,符合redux设计思想

· 实现以同步方式写异步操作,容易理解,逻辑清晰

· 通过发送指令而不是直接调用让异步操作变得容易测试

· 监听、执行自动化

· 提供了丰富强大的指令来完成复杂的操作,比如无阻塞调用,同时执行多个任务等

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

12,react一些主要优点

提高应用性能,虚拟DOM,单向数据流,jsx语法等等

13,React中如何做性能优化

优化关键shouldComponentUpdate:有俩个参数,一个是nextProps,另一个是nextState,而我们就用这俩个上一次的props和state与这一次的props和state去做比较,如果俩者相同,那么就return false,不让它进行更新就可以了。 传参优化以及key值合理使用

14,react如何做到和vue中keep-alive的缓存效果

React Keep Alive 提供了 ,你必须把  放在 Provider 里面,并且每个  组件都必须拥有一个唯一的 key

image.png

15,React中要实现一键换ui样式有哪些方案

1,准备不同主题色的样式文件
2,将用户的选择记录在本地缓存中
3,每次进入应用时,读取缓存,根据缓存的信息判断要加载哪个样式文件即可

16,Redux有几种改变state的方法

唯一修改state通过 store.dispatch() 调用 dispatch()

17,Hooks函数对应的生命周期函数

image.png

18,React如何做路由监听(也可以说是路由守卫)

componentDidMount(){ this.context.router.history.listen((route)=>{ if(route.pathname==='/xxx'){ console.log(1); } }); } 还可以用高阶组件 19,React中jsx语法如何编译成html中的dom树 用Babel来转化

20,shouldComponentUpdate默认会有的吗

是的,每个组件都会有

21,React有哪几种方式改变state

this.forceUpdate this.setState :key值传递不同也可以 replaceState也可以改变

22,Redux和dva的区别

定位:dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。dva = React-Router + Redux + Redux-saga;

image.png

image.png 23,react删除了哪些生命周期 componentWillMount,componentWillReceiveProps,componentWillUpdate等

24,React有哪几种创建组件方法

1. 函数式定义的无状态组件
2. es5原生方式React.createClass定义的组件
3. es6形式的extends React.Component定义的组件

25,react中props和state有什么区别

props 是传递给组件的(类似于函数的形参),而 state 是在组件内被组件自己管理的(类似于在一个函数内声明的变量)

props 是不可修改的,所有 React 组件都必须像纯函数一样保护它们的 props 不被更改。 由于 props 是传入的,并且它们不能更改,因此我们可以将任何仅使用 props 的 React 组件视为 pureComponent,也就是说,在相同的输入下,它将始终呈现相同的输出。 state 是在组件中创建的,一般在 constructor中初始化 state state 是多变的、可以修改,每次setState都异步更新的。

26,React事件机制原理

React事件是合成事件,所有事件都自动绑定到最外层上。因为Virtual DOM 在内存中是以对象的形式存在的,所以React 基于 Virtual DOM 实现了一个 SyntheticEvent (合成事件) 层,我们所定义的事件 处理器会接收到一个 SyntheticEvent 对象的实例。支持事件的冒泡机制,我 们可以使用 stopPropagation() 和 preventDefault()  来中断它。没有兼容问题。

1.事件委派

React并不会把事件处理函数直接绑定到真实的节点上,而是把所有事件绑定到结构的最外层,使用一个统一的事件监听器,这个事件监听器上维持了一个映射来保存所有组件内部的事件监听和处理函数。当组件挂载或卸载时,只是 在这个统一的事件监听器上插入或删除一些对象;当事件发生时,首先被这个统一的事件监听器 处理,然后在映射里找到真正的事件处理函数并调用。这样做简化了事件处理和回收机制,效率 也有很大提升。

  1. 自动绑定

在 React 组件中,每个方法的上下文都会指向该组件的实例,即自动绑定this为当前组件。但是使用 ES6 classes 或者纯函数时,需要手动实现this的绑定

27,虚拟dom优缺点有哪些

缺点:无法直接更新dom 首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。

优点:更新快,dom操作简单,很少内存消耗

28,解释React中时间切片 React 在渲染(render)的时候,不会阻塞现在的线程,如果你的设备足够快,你会感觉渲染是同步的。如果你设备非常慢,你会感觉还算是灵敏的 虽然是异步渲染,但是你将会看到完整的渲染,而不是一个组件一行行的渲染出来 同样书写组件的方式

29,React hookhs有哪些优化手段?

useCallback的使用,把函数及其依赖项作为参数传入 useCallback,它将返回该回调函数的 记忆版本,只有在依赖项有变化的时候才会更新,减少不必要的回调函数创建

useMemo的使用:跟useCallback作用类似,只不过是对计算结果缓存,可以避免不必要的重复计算,这一点跟 Vue 里面的计算属性computed有异曲同工的作用

30,什么是受控组件和非受控组件

受状态控制的组件,必须要有onChange方法,否则不能使用 受控组件可以赋予默认值(官方推荐使用 受控组件) 实现双向数据绑定 form 数据被DOM本身控制,可以用ref获取value,叫非受控组件。