react高频面试题
1、什么是虚拟DOM?
虚拟 DOM (VDOM)是真实 DOM 在内存中的表示。UI 的表示形式保存在内存中,并与实际的 DOM 同步。这是一个发生在渲染函数被调用和元素在屏幕上显示之间的步骤,整个过程被称为调和。
2、虚拟DOM实现的原理?
1)虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象
2)状态变更时,记录新树和旧树的差异
3)最后把差异更新到真正的dom中
3、类组件和函数组件之间的区别是啥?
类组件可以使用其他特性,如状态 state 和生命周期钩子。
当组件只是接收 props 渲染到页面时,就是无状态组件,就属于函数组件,也被称为哑组件或展示组件。
函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。如果都能满足需求的情况下,为了提高性能,尽量使用函数组件。
4、React 中 refs 干嘛用的?
Refs 提供了一种访问在render方法中创建的 DOM 节点或者 React 元素的方法。
可以在组件添加一个 ref 属性来使用,该属性的值是一个回调函数,接收作为其第一个参数的底层 DOM 元素或组件的挂载实例。
5、在 React 中如何处理事件?
为了解决跨浏览器的兼容性问题,SyntheticEvent(事件e) 实例将被传递给你的事件处理函数,SyntheticEvent是 React 跨浏览器的浏览器原生事件包装器,它还拥有和浏览器原生事件相同的接口,包括 stopPropagation() 和 preventDefault()。
6、state 和 props 区别是啥?
props和state是普通的 JS 对象。虽然它们都包含影响渲染输出的信息,但是它们在组件方面的功能是不同的。即
1)state 是组件自己管理数据,控制自己的状态,可变;
2)props 是外部传入的数据参数,不可变;
3)没有state的叫做无状态组件,有state的叫做有状态组件;
4)多用 props,少用 state,也就是多写无状态组件。
7、如何创建 refs?
Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们。
8、什么是高阶组件?
高阶组件(HOC)是接受一个组件并返回一个新组件的函数。基本上,这是一个模式,是从 React 的组合特性中衍生出来的,称其为纯组件,因为它们可以接受任何动态提供的子组件,但不会修改或复制输入组件中的任何行为。
9、在构造函数调用 super
并将 props
作为参数传入的作用是啥?
在调用 super() 方法之前,子类构造函数无法使用this引用,ES6 子类也是如此。将 props 参数传递给 super() 调用的主要原因是在子构造函数中能够通过this.props来获取传入的 props。
10、什么是控制组件?
在 HTML 中,表单元素如 <input>、<textarea>和<select>通常维护自己的状态,并根据用户输入进行更新。当用户提交表单时,来自上述元素的值将随表单一起发送。
而 React 的工作方式则不同。包含表单的组件将跟踪其状态中的输入值,并在每次回调函数(例如onChange)触发时重新渲染组件,因为状态被更新。以这种方式由 React 控制其值的输入表单元素称为受控组件。
11、讲讲什么是 JSX ?
jsx是JavaScript的一种语法扩展,它跟模板语言很接近,但是它充分具备JavaScript的能力
当 Facebook 第一次发布 React 时,他们还引入了一种新的 JS 方言 JSX,将原始 HTML 模板嵌入到 JS 代码中。JSX 代码本身不能被浏览器读取,必须使用Babel和webpack等工具将其转换为传统的JS。
JSX中的标签可以是单标签,也可以是双标签,但必须保证标签是闭合的。
12、为什么不直接更新 state
呢 ?
如果试图直接更新 state ,则不会重新渲染组件。
需要使用setState()方法来更新 state。它调度对组件state对象的更新。当state改变时,组件通过重新渲染来响应。
13、React 组件生命周期有哪些不同阶段?
在组件生命周期中有四个不同的阶段:
1)Initialization:在这个阶段,组件准备设置初始化状态和默认属性。
2)Mounting:react 组件已经准备好挂载到浏览器 DOM 中。这个阶段包括componentWillMount和componentDidMount生命周期方法。
3)Updating:在这个阶段,组件以两种方式更新,发送新的 props 和 state 状态。此阶段包括shouldComponentUpdate、componentWillUpdate和componentDidUpdate生命周期方法。
4)Unmounting:在这个阶段,组件已经不再被需要了,它从浏览器 DOM 中卸载下来。这个阶段包含 componentWillUnmount 生命周期方法。
除以上四个常用生命周期外,还有一个错误处理的阶段:
5)Error Handling:在这个阶段,不论在渲染的过程中,还是在生命周期方法中或是在任何子组件的构造函数中发生错误,该组件都会被调用。这个阶段包含了 componentDidCatch 生命周期方法。
14、React 的生命周期方法有哪些?
1)componentWillMount:在渲染之前执行,用于根组件中的 App 级配置。
2)componentDidMount:在第一次渲染之后执行,可以在这里做AJAX请求,DOM 的操作或状态更新以及设置事件监听器。
3)componentWillReceiveProps:在初始化render的时候不会执行,它会在组件接受到新的状态(Props)时被触发,一般用于父组件状态更新时子组件的重新渲染
4)shouldComponentUpdate:确定是否更新组件。默认情况下,它返回true。如果确定在 state 或 props 更新后组件不需要在重新渲染,则可以返回false,这是一个提高性能的方法。
5)componentWillUpdate:在shouldComponentUpdate返回 true 确定要更新组件之前件之前执行。
6)componentDidUpdate:它主要用于更新DOM以响应props或state更改。
7)componentWillUnmount:它用于取消任何的网络请求,或删除与组件关联的所有事件监听器。
15、使用 React Hooks 好处是啥?
首先,Hooks 通常支持提取和重用跨多个组件通用的有状态逻辑,而无需承担高阶组件或渲染 props 的负担。Hooks 可以轻松地操作函数组件的状态,而不需要将它们转换为类组件。
Hooks 在类中不起作用,通过使用它们,咱们可以完全避免使用生命周期方法,例如 componentDidMount、componentDidUpdate、componentWillUnmount。相反,使用像useEffect这样的内置钩子。
16、什么是 React Hooks?
Hooks是 React 16.8 中的新添加内容。它们允许在不编写类的情况下使用state和其他 React 特性。使用 Hooks,可以从组件中提取有状态逻辑,这样就可以独立地测试和重用它。Hooks 允许咱们在不改变组件层次结构的情况下重用有状态逻辑,这样在许多组件之间或与社区共享 Hooks 变得很容易。
17、React 中的 useState()
是什么?
useState 是一个内置的 React Hook。useState(0) 返回一个元组,其中第一个参数count是计数器的当前状态,setCounter 提供更新计数器状态的方法。
可以在任何地方使用setCounter方法更新计数状态-在这种情况下,咱们在setCount函数内部使用它可以做更多的事情,使用 Hooks,能够使咱们的代码保持更多功能,还可以避免过多使用基于类的组件。
18、React 中的StrictMode(严格模式)是什么?
React 的StrictMode是一种辅助组件,可以帮助咱们编写更好的 react 组件,可以使用<StrictMode />包装一组组件,并且可以帮咱们以下检查:
1)验证内部组件是否遵循某些推荐做法,如果没有,会在控制台给出警告。
2)验证是否使用的已经废弃的方法,如果有,会在控制台给出警告。
3)通过识别潜在的风险预防一些副作用。
19、为什么类方法需要绑定到类实例?
在 JS 中,this 值会根据当前上下文变化。在 React 类组件方法中,开发人员通常希望 this 引用组件的当前实例,因此有必要将这些方法绑定到实例。
20、受控组件和非受控组件区别是啥?
受控组件是 React 控制中的组件,并且是表单数据真实的唯一来源。
非受控组件是由 DOM 处理表单数据的地方,而不是在 React 组件中。
尽管非受控组件通常更易于实现,因为只需使用refs即可从 DOM 中获取值,但通常建议优先选择受控制的组件,而不是非受控制的组件。
这样做的主要原因是受控组件支持即时字段验证,允许有条件地禁用/启用按钮,强制输入格式。
21、如何避免组件的重新渲染?
React 中最常见的问题之一是组件不必要地重新渲染。React 提供了两个方法,在这些情况下非常有用:
1)React.memo():这可以防止不必要地重新渲染函数组件
2)PureComponent:这可以防止不必要地重新渲染类组件
这两种方法都依赖于对传递给组件的props的浅比较,如果 props 没有改变,那么组件将不会重新渲染。虽然这两种工具都非常有用,但是浅比较会带来额外的性能损失,因此如果使用不当,这两种方法都会对性能产生负面影响。
通过使用 React Profiler,可以在使用这些方法前后对性能进行测量,从而确保通过进行给定的更改来实际改进性能。
22、如何避免在React重新绑定实例(解决this指向)?
有几种常用方法可以避免在 React 中绑定方法:
1)将事件处理程序定义为内联箭头函数
2)使用箭头函数来定义方法
3)使用带有 Hooks 的函数组件
23、React组件通信如何实现?
React组件间通信方式:
1)父组件向子组件通讯: 父组件可以向子组件通过传 props 的方式,向子组件进行通讯
2)子组件向父组件通讯: props+回调的方式,父组件向子组件传递props进行通讯,此props为作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中
3)兄弟组件通信: 找到这两个兄弟节点共同的父节点,结合上面两种方式由父节点转发信息进行通信
4)跨层级通信: Context设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言,对于跨越多层的全局数据通过Context通信再适合不过
5)发布订阅模式: 发布者发布事件,订阅者监听事件并做出反应,我们可以通过引入event模块进行通信
6)全局状态管理工具: 借助Redux或者Mobx等全局状态管理工具进行通信,这种工具会维护一个全局状态中心Store,并根据不同的事件产生新的状态
24、React如何进行组件/逻辑复用?
1)高阶组件:
(1)属性代理
(2)反向继承
2)渲染属性
3)react-hooks
25、redux的工作流程?
首先,我们看下几个核心概念:
1)Store:保存数据的地方,你可以把它看成一个容器,整个应用只能有一个Store。
2)State:Store对象包含所有数据,如果想得到某个时点的数据,就要对Store生成快照,这种时点的数据集合,就叫做State。
3)Action:State的变化,会导致View的变化。但是,用户接触不到State,只能接触到View。所以,4)State的变化必须是View导致的。Action就是View发出的通知,表示State应该要发生变化了。
5)Action Creator:View要发送多少种消息,就会有多少种Action。如果都手写,会很麻烦,所以我们定义一个函数来生成Action,这个函数就叫Action Creator。
6)Reducer:Store收到Action以后,必须给出一个新的State,这样View才会发生变化。这种State的计算过程就叫做Reducer。Reducer是一个函数,它接受Action和当前State作为参数,返回一个新的State。
7)dispatch:是View发出Action的唯一方法。
然后整个工作流程:
1)首先,用户(通过View)发出Action,发出方式就用到了dispatch方法。
2)然后,Store自动调用Reducer,并且传入两个参数:当前State和收到的Action,Reducer会返回新的State。
3)State一旦有变化,Store就会调用监听函数,来更新View。
26、redux中如何进行异步操作?
当然,我们可以在componentDidmount中直接进行请求无须借助redux.
但是在一定规模的项目中,上述方法很难进行异步流的管理,通常情况下我们会借助redux的异步中间件进行异步处理.
redux异步流中间件其实有很多,但是当下主流的异步中间件只有两种redux-thunk、redux-saga,当然redux-observable可能也有资格占据一席之地,其余的异步中间件不管是社区活跃度还是npm下载量都比较差了。