React常见面试题(2024最新版)

本文深入探讨React的关键概念,包括虚拟DOM、Diff算法、keys的作用、State与Props的区别,以及异步setState。同时,讲解了受控与非受控组件、展示与容器组件、高阶组件和React Hooks的应用,揭示React组件通信的多种方式,如props、Context、Redux等。
摘要由CSDN通过智能技术生成

创建项目

npx create-react-app my-app

启动项目

npm start

目录结构

目录/文件名 描述
README.md 项目的自述文件
node_modules/ 项目依赖包存放目录
package.json 包管理配置文件,记录项目信息和依赖
package-lock.json 锁定依赖版本,确保跨环境一致性
public/ 公共资源目录
public/index.html 主 HTML 文件,React 应用将被引入到这里
public/favicon.ico 网站图标
public/manifest.json PWA 配置文件
src/ 源代码目录
src/components 通用功能组件
src/pages 页面组件
src/router 路由文件
src/store Redux 状态管理相关的代码
src/store/modules Redux 各个子模块
src/store/index.js Redux 组装各个子模块的文件
src/App.css App组件的样式文件
src/App.js 应用的主要组件
src/App.test.js App组件的测试文件
src/index.css 入口样式文件
src/index.js 应用的入口文件
src/logo.svg 示例 logo 文件
src/reportWebVitals.js Web Vitals 性能监测报告工具
src/setupTests.js 测试环境设置文件
.gitignore Git 版本控制系统忽略文件规则
.eslintrc.json ESLint 配置文件,用于代码风格检查
.gitattributes Git 属性配置文件
yarn.lock (如果使用 Yarn)锁定依赖版本的文件

Virtual DOM 是什么?

虚拟 DOM 是以 JS 对象的形式模拟真实 DOM。虚拟 DOM 并不直接与用户交互,而是作为实际 DOM 的抽象和中间层存在。通过 Diff 算法对比新旧虚拟 DOM 树的差异,精确地找出哪些部分发生了变化,从而对真实 DOM 中变动的部分进行最小化更新,而非重新渲染整个页面。

什么是 Diff 算法?它是如何进行比较的?

一种用于确定并计算两个对象(通常是虚拟 DOM 树)差异的算法。其核心目的是为了高效地更新用户界面(UI)。React 的 Diff 算法专注于找出新旧虚拟 DOM 树之间的最小变化集,以便尽可能快速且高效地将这些变化应用到实际的 DOM 上,以此达到 UI 的快速更新,同时减少不必要的重渲染,提升性能。

  • 分层比较(Tree Diff):首先对树进行分层遍历,而不是一次性比较整个树的所有节点。这意味着 React 只会对位于同一层级的节点进行比较,而不会跨层级直接比较。这样可以显著减少比较的复杂性。
  • 同层节点遍历:在每一层,React 从左到右遍历子节点。对于每个节点,它检查新旧节点的类型是否相同。如果类型不同,React 认为这是一个重大变更,会直接替换整个子树;如果类型相同,则继续比较属性和子节点。
  • 元素类型与属性比较:当节点类型相同时,React 会检查属性是否有变化。如果有属性变更,React 会尽可能地就地更新这些属性,而不是替换整个元素。
  • 列表比较与 Key 的作用:对于子节点是列表的情况,React 依赖于列表中每个元素的唯一 key 属性来优化比较。通过 key,React 能快速确定哪些元素是新增的、删除的或是位置发生了变化,从而减少不必要的创建和销毁操作。没有 key 或错误使用 key 会导致 React 采取较为低效的比较策略。
  • Component Diff:对于组件,React 会比较组件的类型。如果类型相同,它可能会复用已存在的组件实例并仅更新 props。如果类型不同,React 将卸载旧组件并创建新组件。

React 中 keys 的作用是什么?

key 是 React 中用于追踪哪些列表中元素被修改、删除或者被添加的辅助标识。在 Diff 算法中,key 用来判断该元素节点是被移动过来的还是新创建的元素,减少不必要的元素重复渲染。

State 和 Props 的区别是什么?

相同点
Props 和 State 是普通的 JS 对象,它们都是用来保存信息的。

不同点
State(状态):是组件自己管理数据、控制自己的状态,可以修改。
Props(属性): 是外部传入的数据参数,不可修改。

注意点:
没有 State 的叫做无状态组件,有 State 的叫做有状态组件。
多用 Props,少用 State,也就是多写无状态组件。

setState 是同步的还是异步的?

setState 通常是异步的,React 会将多个 setState 函数合并成一个队列,然后批量更新组件。

如果改变状态的代码处于某个 HTML 元素的事件中,则其是异步的,都则是同步。

什么是受控组件和非受控组件?

非受控组件:表单元素的值不由 React 直接管理,而是直接从 DOM 中读取,常使用 Ref 属性来访问 DOM 元素。
受控组件:通过 setState 将表单元素的值维护到了 state 中,需要时再从 state 中取出,这里的数据就受到了 state 的控制,称为受控组件。

什么是展示组件和容器组件?

展示组件(Presentational Components):通常是无状态的,接收来自容器组件的 Props。主要负责 UI 的呈现,即组件的外观和布局。它们专注于如何将数据渲染成用户可见的界面。
容器组件(Container Components):通常是有状态(state)的。负责管理数据和业务逻辑,决定组件如何运作。它们与数据源交互,如 API 调用、Redux store 等,并将数据传递给展示组件。

什么是高阶组件?

高阶组件(Higher-Order Components 简称 HOC)是一种函数,接受一个组件作为参数并返回一个新的组件。高阶组件内部可以对传入的组件进行包装,添加额外的属性(props)、状态管理、生命周期方法或者其他逻辑。用于实现组件的复用、逻辑的抽象和代码的组合。

React Hooks 是什么?

React Hooks 是 React 16.8 版本引入的一个特性,它允许你在不编写 class 组件的情况下使用 state 和其他 React 特性。Hooks 让函数组件也能拥有状态管理和生命周期方法等功能,从而简化组件结构,提高代码的可读性和可维护性。

useRef()和 React.createRef()的区别?

useRef():在每一次组件更新,再次执行 useRef 方法的时候,不会创建新的 ref 对象,获取到的还是第一次创建的 ref 对象(函数组件推荐使用)。
createRef():在每一次组件更新的时候,会创建一个新的 ref 对象,比较浪费性能(类组件推荐使用)。

常见或常用的 Hooks 有哪些?

useState():在函数组件中使用状态,修改状态值,更新视图。
useRef():在函数组件中获取 DOM 元素。
useEffect():在函数组件中执行副作用操作,如数据获取、订阅、定时器等。简单来说就是模拟类组件的生命周期。在第一个参数(回调函数)中,再 return 一个函数,可以清除副作用(比如:清除定时器)。
useMemo():在函数组件重新渲染时缓存计算结果,避免重复计算。类似于 Vue 的 computed。
useReducer():用来操作复杂的组件状态逻辑。参数分别是 reducer 函数和初始状态,根据 action.type 执行对行类型操作。
useCallback():在函数组件中缓存函数,避免函数每次渲染都创建新的函数。简单来说当父组件重新渲染的时候因为传递了函数给子组件,子组件也会跟着渲染。当使用 useCallback 包裹函数后,可以避免每次重新渲染都创建新的函数。
useContext():用于多层组件实现数据共享,无需显式地传递 props。
有待补充

React.memo()是什么?

React.memo() 是一个高阶组件,用于优化组件的渲染。当组件的 props 没有变化时,React.memo() 会阻止组件的渲染。
注意:调用 React.memo() 会返回一个新的组件。

import {
    useState, memo } from "react";
// React默认渲染机制,只要父组件更新,子组件也会重新渲染
// 父组件点击按钮改变名字时,子组件也会跟着修改,但其实子组件并没有改变
// 这个时候子组件没必要重新渲染
const MemoSon = memo(function Son(props) {
   
  console.log("Son", props);
  return (
    <div>
      <h3>Son</h3>
    </div>
  );
});

function App() {
   
  const [count, setCount] = useState(0);
  const [name, setName] = useState("zhangsan");
  return (
    <div>
      <h1>App</h1>
      <MemoSon count={
   count} />
      <button onClick={
   () => setCount
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值