React 前端导航

React 常见面试问题附答案,持续更新中

React 常见面试问题附答案,持续更新中

本文主要记录日常面试中遇到的问题及其参考答案,如有表述有误的地方欢迎大家指出,共同进步!

技术问题

基础

1.什么是虚拟DOM?实现原理?
Virtual DOM(虚拟DOM),是由普通的 JS 对象来描述DOM对象,因为不是真实的DOM对象,所以叫 Virtual DOM。

2.类组件和函数组件之间的区别?

  • 类组件有生命周期函数,函数组件中没有
  • 类组件顾名思义就有类的特性,有类的三大特性,继承、封装、多态,有内部状态,而函数组件只能通过 hook 保存内部状态。
  • 只能在函数组件中使用hooks

3.在 React 中如何处理事件?
React 元素的事件处理和 DOM 元素类似。但是有一点语法上的不同:

  • React 事件绑定属性的命名采用驼峰式写法,而不是小写。
  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)

4.state 和 props 区别?
state是可变的,而props不可变。

5.什么是高阶组件?
高阶组件(Higher Order Components,简称:HOC)不是我们理解的React中的组件,而是一种组件逻辑复用的技术手法,他实际就是一个以组件为参数并返回一个新的的组件的函数,用于增强和优化我们的参数组件,例如我们常用到的 redux 中的connect函数,withRouter函数都是高阶组件,用于向基础组件中注入更多数据。

6.什么是JSX?
JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

7.为什么类方法需要绑定 this?
在 React 类组件中,由于将事件处理函数引用作为回调传递后,事件处理程序方法会丢失其隐式绑定的上下文,导致 this 值会回退到默认绑定,变成 undefined。更通俗的讲,就是事件处理函数被传递后,作用域发生了改变,丢掉了原先的this。示例如下:

<button type="button" onClick={this.handleClick}>
   Click Me
</button>

有人可能会问:既然是依据“默认绑定规则”,不应该指向全局对象window或global吗?
这是因为,类声明和类表达式的主体(构造函数、静态方法和原型方法)以 严格模式 执行。在严格模式下,默认绑定this会指向undefined。

8.React 中的StrictMode(严格模式)是什么?
StrictMode 是一个用以标记出应用中潜在问题的工具。就像 Fragment ,StrictMode 不会渲染任何真实的UI。它为其后代元素触发额外的检查和警告。
StrictMode目前有助于:

  • 识别具有不安全生命周期的组件
  • 有关旧式字符串ref用法的警告
  • 检测意外的副作用
  • 检测遗留 context AP

9. class组件声明周期函数有哪些?

挂载:当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

更新:当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

卸载:当组件从 DOM 中移除时会调用如下方法:

  • componentWillUnmount()

错误处理:当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:

  • static getDerivedStateFromError()
  • componentDidCatch()

10.React Hooks 的优缺点?

  • 相比render props 和高阶组件,更容易复用组件状态逻辑

进阶

1. 遍历数组循环生成节点时需要给节点设置key属性,这个key有什么作用?
当我们需要渲染一个列表的时候,React 会存储这个列表每一项的相关信息,当我们要更新这个列表时,React 需要确定哪些项发生了改变。我们有可能增加、删除、重新排序或者更新列表项。
在 React 中采用的是 diff 算法来对比新旧虚拟节点,从而更新节点。 在交叉对比中,当新节点跟旧节点头尾交叉对比没有结果时,会根据新节点的 key 去对比旧节点数组中的 key ,从而找到相应旧节点(这里对应的是一个key => index 的map映射)。如果没找到就认为是一个新增节点。而如果没有key,那么就会采用遍历查找的方式去找到对应的旧节点。一种一个 map 映射,另一种是遍历查找。相比而言。map 映射的速度更快。
其实如果说只是文本内容改变了,不写key反而性能和效率更高,主要是因为不写key是将所有的文本内容替换一下,节点不会发生变化,而写 key 则涉及到了节点的增和删,发现旧 key 不存在了,则将其删除,新 key 在之前没有,则插入,这就增加性能的开销。当然在我们正常的开发中,这种及其简单的更新是很少见的,大部分还是复杂的内容更新,所以按大局来说还是写 key 的效率高一些,写 key 增加的这一点点的性能开销在用户的视角上时感知不到的。
所以说 key 是给每一个 vnode 的唯一 id ,可以依靠 key ,更准确更快的拿到oldVnode中对应的vnode节点,高效和准确的更新节点。

2. React 中你是怎么做性能优化的?

  • 函数组件使用Memo缓存组件,类组件合理使用 PureComponent 或 shouldComponentUpdate 钩子函数,避免组件的无效更新
  • 组件懒加载,按需加载,避免包体大加载慢
  • 使用 React Fragments 避免额外标记

3. React 中如何做的状态管理?
4. Redux 用了什么设计模式?你用过之后感觉有什么缺点或者说不好用的地方
5. 如何理解 React 中的 refs, 有哪些实用场景?
6. React 组件之间如何通信?

  • 父子组件之间 通过 props 参数传递
  • Context 共享数据
  • redux 全局数据共享

7. React hooks 解决了什么问题?常用的 hooks 有哪些?
8. React hooks使用有哪些注意事项
9. React useMemo 与 useCallback 的区别以及主要的应用场景?
10. useEffect 的用法, 有哪些参数,如何检测数组依赖项的变化?
11. React Hooks 闭包问题知道吗,为什么会有这个问题,如何避免?
12. React Class 组件中请求可以在 componentWillMount 中发起吗?为什么?**
可以发起,但是React推荐在componentDidMount中执行,因为它执行时DOM已加载完毕,部分依赖更新dom而发起的请求在它内部写更加合理,并且在服务端渲染时,此函数会被执行两次,而DidMount并不会在服务端执行. 16.简要说明 React Hook 中 useState 和 useEffect 的运行原理?
13.React 如何发现重渲染、什么原因容易造成重渲染、如何避免重渲染?
14.React Hook 和闭包有什么关联关系?
15.React 中 useState 是如何做数据初始化的?
16.React中的Diff细节可以讲一下吗,是所有Fiber都需要Diff吗,React做了什么优化?又可能存在什么缺陷.
17.setState是异步的吗?给出理由?
18.说一下HOC、render props?
19.说一下React中的时间分片?
20.详细描述一下React-redux和redux和React自带跨组件传参?
21.React中绑定的事件是原生的吗?不是的话和原生事件有什么差别?React是如何做到平台统一?
22.React 如何进行组件/逻辑复用?
23.什么场景需要用React Portals?
24.React 如何异步加载组件?
25.Redux 如何处理异步action,如何实现的?

场景应用问题

1.给出以下代码,x会被打印几次?

import * as React from "react";
import { useState, useEffect } from "react";
import { createRoot } from "react-dom/client";

function SetStatePage(props) {
  const [ count, setCount ] = useState(-1);
  useEffect(() => {
    setCount(0)
  });
  console.log("x"); //sy-log
  return (
    <div>
      <h3>SetStatePage</h3>
    </div>
  );
}
const root = createRoot(document.getElementById("root"));
root.render(<SetStatePage />);
console.log("React", React.version); //sy-log

2.看代码,log打印几次?

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom/client";

ReactDOM.createRoot(document.getElementById("root")!).render(<App />);

function App() {
  const [count, setCount] = useState(-1);
  useEffect(() => {
    setCount(0);
  });
  // 打印几次?
  console.log("app render", count);
  return <p>hello world {count}</p>;
}

声明:本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。邮箱:farmerlzj@163.com。 本站原创内容未经允许不得转载,或转载时需注明出处: 内容转载自: React前端网:https://qianduan.shop/blogs/detail/55

#react#面试题

相关推荐

react中实现markdown文件读取展示

react中实现markdown文件读取展示

umi实践问题汇总--持续更新

在使用umi的过程中所遇到问题的记录汇总