2025 年开发者必知的 17 个 React 面试问题,感谢阅读

2025-06-07

2025 年开发者必知的 17 个 React 面试问题

感谢阅读

最初发表于Medium

React是2025年前端开发人员最需要的技能之一。如果你正在准备2025 年的React开发人员面试,那么掌握最新的最佳实践、模式和概念至关重要。

本文列出了17 个 React 面试问题,涵盖了从核心React原则到高级性能优化的所有内容,可帮助您在下一次React开发人员面试中脱颖而出。

让我们开始吧!

深入探索

1. 什么是 React Virtual DOM?它与真实 DOM 和 Shadow DOM 有何不同?

虚拟 DOM是一种概念,其中真实 DOM的虚拟表示保存在内存中,并且仅在必要时通过ReactDOM等库与实际DOM同步。

虚拟DOM是一个代表内存中真实 DOM 的对象。由于DOM更新是任何 Web 应用不可或缺的一部分,但却是前端开发中最昂贵的操作,因此虚拟 DOM用于检查应用中需要更新的部分,并仅更新这些部分,从而显著提升性能。

虚拟DOM与真实 DOM影子 DOM是完全不同的概念真实 DOMHTML 文档树状结构的实际表示,浏览器使用它来跟踪网页的内容;而影子 DOM是一种编程实践,允许开发人员为 Web 应用程序创建独立的可重用组件。

如果你想深入了解虚拟 DOM真实 DOM影子 DOM之间的区别,请查看这篇文章

2. React 中有哪两种类型的组件?我们应该在哪里使用它们?

React中有两种类型的组件

  1. 类组件
  2. 功能组件

以前,类组件是创建具有React中任何功能的组件的唯一方法,而功能组件仅用作展示组件,通常被称为“哑”组件。

但是,随着React 16.8的发布和React Hooks的引入函数式组件现在可以拥有状态和生命周期方法,使它们成为在React中创建组件的首选方式

函数式组件比类组件速度更快,开销和样板代码也更少,因此建议尽可能使用函数式组件。然而,某些生命周期方法仍然只能在类组件中使用,因此在某些特殊情况下,例如创建自定义错误边界(例如:在类组件中使用生命周期方法),你可能需要使用类组件。componentDidCatch

3. 为什么 React 中需要键?在 React 中,我们可以不使用列表而直接使用键吗?

键

KeysReact中,用于标识唯一的虚拟 DOM 元素及其驱动UI 的对应数据。使用keys可帮助React通过回收现有DOM 元素来优化渲染

Keys帮助React识别哪些项目已更改、添加或删除,使其能够重用已经存在的DOM 元素,从而提高性能。

例如:

const Todos = ({ todos }) => {
  return (
    <div>
      {todos.map((todo) => (
        <li>{todo.text}</li>
      ))}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

这将导致每次待办事项更改时都会创建新的DOM 元素key,但添加prop(即<li key={todo.id}>{todo.text}</li>:)将导致“拖动”标签内的DOM元素ul并仅更新必要li

Keys可以与React中的任何元素一起使用,不一定需要与列表一起使用,但最常用于列表以优化渲染。一些非标准(且不推荐)的用例keys包括使用它们来强制重新渲染组件,如下例所示:

const TimeNow = () => {
  const [key, setKey] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => setKey((prevKey) => prevKey + 1), 1000);
    return () => clearInterval(interval);
  }, []);

  return <div key={key}>{new Date()}</div>;
};
Enter fullscreen mode Exit fullscreen mode

如上所述,绝对应该避免使用这样的代码,最好使用状态来存储时间,而不是使用键来强制重新渲染。使用keys强制重新渲染是一种反模式,除非你确切知道自己在做什么,否则可能会导致严重的性能问题。

4. React 中受控输入和非受控输入的区别

受控组件依赖React 状态来管理表单数据,而非受控组件使用DOM本身来处理表单数据。

在大多数情况下,受控组件是首选,因为它们为表单数据提供了单一真实来源,从而更易于管理、验证和提交表单数据。

const ControlledInputForm = () => {
  const [value, setValue] = useState("");
  const handleChange = (e) => setValue(e.target.value);
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" value={value} onChange={handleChange} />
      <button type="submit">Submit</button>
    </form>
  );
};

const UncontrolledInputForm = () => {
  const inputRef = useRef(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
};
Enter fullscreen mode Exit fullscreen mode

5.为什么我们需要转译 JSX 代码?

除非你伤到了头,否则你不会像这样使用React :

import { createElement } from "react";

const Greeting = ({ name }) => {
  return createElement("h1", { className: "greeting" }, "Hello");
};
Enter fullscreen mode Exit fullscreen mode

然而,这就是浏览器读取的内容——它根本无法理解通常用于编写React 组件的JSX 语法

因此,我们需要使用Babel之类的工具将JSX 转换JavaScript,以便浏览器可以执行它。因此,当你编写以下代码时:

const Greeting = ({ name }) => <h1 className="greeting">Hello</h1>;
Enter fullscreen mode Exit fullscreen mode

它被转换为前面的代码片段,以便浏览器可以解释它并呈现组件。

6.JSX 如何防止注入攻击?

注射

由于JSX将内容渲染为文本,因此用户输入的任何元素都不会被视为HTML,而只是纯文本。例如,以下script标签将被渲染为文本,而不会执行:

const MyComponent = () => {
  const content = "<script>alert('XSS')</script>";
  return <div>{content}</div>;
};
Enter fullscreen mode Exit fullscreen mode

注意:您可以使用来覆盖此行为,dangerouslySetInnerHTML但不建议这样做,除非您绝对确定输入的来源(并且强烈建议在注入之前清理内容)。

const MyComponent = () => {
  const content = "<script>alert('XSS')</script>";
  return <div dangerouslySetInnerHTML={{ __html: content }} />;
};
Enter fullscreen mode Exit fullscreen mode

7. 如何为 React 组件添加样式?

CSS 文件

使用CSS文件是设置React 组件样式的最常用方法之一。它允许使用所有CSS特性,并且在Create React App中已默认设置

/* Button.css */
.button {
  background-color: blue;
  color: white;
}
Enter fullscreen mode Exit fullscreen mode
// Button.tsx
import "./Button.css";

const Button = () => {
  return <button className="button">Click me</button>;
};
Enter fullscreen mode Exit fullscreen mode

内联 CSS

使用内联CSS为React 元素添加样式,可以将样式完全限定在元素范围内。但是,某些样式功能不适用于内联样式。例如,像 这样的伪类的样式。:hover

const Button = () => {
  return (
    <button style={{ backgroundColor: "blue", color: "white" }}>
      Click me
    </button>
  );
};
Enter fullscreen mode Exit fullscreen mode

CSS-in-JS 模块(Styled Components、Emotion 和 Styled-jsx)

CSS-in-JS模块是设计React 应用程序样式的热门选择,因为它们与React 组件紧密集成。例如,它们允许样式在运行时根据React props进行更改。此外,默认情况下,大多数此类系统会将所有样式限定在相应的组件上。

import styled from "styled-components";

const Button = styled.button`
  background-color: blue;
  color: white;
`;

const App = () => {
  return <Button>Click me</Button>;
};
Enter fullscreen mode Exit fullscreen mode

CSS 模块

我个人最喜欢的样式方法,CSS 模块允许将样式限定在单个组件内。这是一种避免类名冲突(类名冲突指的是两个名相同——这在大型项目中很常见)的好方法,可以保持样式的井然有序,并能将共享样式添加到多个组件。

/* Button.module.css */
.button {
  background-color: blue;
  color: white;
}
Enter fullscreen mode Exit fullscreen mode
// Button.js
import styles from "./Button.module.css";

const Button = () => {
  return <button className={styles.button}>Click me</button>;
};
Enter fullscreen mode Exit fullscreen mode

8. React 中的合成事件是什么?

合成事件将不同浏览器原生事件的响应组合成一个 API,确保事件在不同浏览器中保持一致。无论应用程序在哪个浏览器中运行,它都是一致的。

const Component = () => {
  const handleClick = (e) => {
    e.preventDefault(); // synthetic event
    console.log("link clicked");
  };
  return <a onClick={(e) => handleClick}>Click me</a>;
};
Enter fullscreen mode Exit fullscreen mode

9.React 中的严格模式是什么?

<StrictMode />是React内置的一个组件,用于提供组件中潜在问题的额外可见性。如果应用程序在开发模式下运行,则任何出现的问题都会记录到开发控制台中;但如果应用程序在生产模式下运行,则不会显示这些警告

开发人员使用它<StrictMode />来查找诸如弃用的生命周期方法遗留模式等问题,以确保所有React 组件都遵循当前的最佳实践。

<StrictMode />可以应用于应用程序组件层次结构的任何级别,从而允许在代码库中逐步采用它。

文档<StrictMode />添加如下

严格模式支持以下仅限开发的行为:

10. 如何优雅地处理 React 中的错误?

默认情况下,如果React 应用在渲染过程中抛出错误,React会将其 UI 从屏幕上移除。为了防止这种情况,我们可以将部分 UI 包裹到错误边界中,这样我们就可以捕获错误并显示回退 UI,而不会导致整个应用崩溃。

您可以构建自定义错误边界:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI, or even accept it as a prop
      return <FallbackComponent />;
    }
    return this.props.children;
  }
}
Enter fullscreen mode Exit fullscreen mode

但大多数情况下,您可以使用react-error-boundary提供必要组件来处理React 应用程序中的错误。

import { ErrorBoundary } from "react-error-boundary";

const App = () => (
  <ErrorBoundary FallbackComponent={FallbackComponent}>
    <MyComponent />
  </ErrorBoundary>
);
Enter fullscreen mode Exit fullscreen mode

11.React Hooks 的规则是什么?

React Hooks有 3 条主要规则

  1. 仅从 React 函数中调用 HooksHooks只能在React 函数组件中或从其他Hooks中调用。在常规JS / TS函数中调用Hooks将被视为常规函数调用,并且无法按预期工作。
  2. 仅在顶层调用 hooksHooks只能在React 函数组件自定义 hooks的顶层调用。这是为了确保每次组件渲染时hooks都以相同的顺序调用。在循环条件嵌套函数中使用hooks将导致错误。
  3. Hooks 必须以 'use' 开头:所有hooks 的名称(包括自定义 hooks )都必须以"use"开头。这是为了确保React能够识别hooks并强制执行hooks的规则。例如,useStateuseEffectuseContext等等。

12. 如何处理 React 函数组件中的常见生命周期方法?

React常见的生命周期方法有:

  • componentDidMount:组件挂载到DOM后调用。通常用于获取数据或执行诸如添加事件监听器之类的副作用
  • componentDidUpdate:在组件中某个特定值更新后调用。通常用于根据更新后的值执行一些副作用。
  • componentWillUnmount:组件从DOM中卸载之前调用的清理方法。通常用于移除事件监听器取消网络请求

在函数式组件,这些生命周期方法可以通过使用useEffect钩子来处理。useEffect钩子的第一个参数是一个函数,第二个参数是一个依赖项数组。

const Component = () => {
  useEffect(() => {
    // componentDidMount
    console.log("Component mounted");

    return () => {
      // componentWillUnmount
      console.log("Component unmounted");
    };
  }, []); // empty dependency array implies this effect runs only once when the component mounts

  useEffect(
    () => {
      // componentDidUpdate
      console.log("Component updated");
    },
    [
      /* dependencies - changes to these values should trigger the function to re-run */
      /* NOTE: This function will run during mount too */
    ]
  );

  return <React.Fragment />;
};
Enter fullscreen mode Exit fullscreen mode

13. React 中的 refs 是什么?

Refs是允许您在渲染之间保留数据的变量,就像变量一样state,但与state变量不同的是,更新refs不会导致组件重新渲染

Refs通常用于(但不限于)存储对DOM 元素的引用。

const Component = () => {
  const inputRef = useRef(null);
  const handleClick = () => inputRef.current.focus();

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={handleClick}>Focus Input</button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

14. React 中的 prop 钻孔是什么?如何避免它?

钻头

在开发React 应用程序时,经常需要将数据从层次结构中较高的组件传递到深度嵌套的组件。Prop钻取是指将props从源组件通过所有中间组件传递到深度嵌套组件的过程。

使用prop 钻取的缺点是,原本不应该知道数据的组件可以访问数据,而且代码变得更难维护。

可以使用Context API或某种形式的状态管理库来避免Prop 钻取

15. 描述 React 中的一些优化技术

使用记忆化

useMemo是一个用于缓存CPU 开销大函数的React hook由于组件重新渲染而反复调用CPU 开销大函数可能会导致严重的性能问题用户体验下降

useMemo 钩子可用于缓存此类函数的结果。通过使用useMemo仅在需要时调用CPU 开销较大的函数。

延迟加载

延迟加载是一种用于减少React 应用初始加载时间的技术。通过在用户浏览应用时加载组件,它有助于将 Web 应用性能风险降至最低。

节流和去抖

虽然这不是React 独有的优化技术,但它经常在React 应用程序中用于提升性能。节流去抖是用于限制函数响应事件调用次数的技术——它们通常与为用户提供实时反馈的输入一起使用(例如:在带有自动建议的搜索字段中输入内容——可以对获取建议的API 调用进行节流去抖动,以避免进行不必要的API 调用)。

16.什么是门户?

门户网站

建议使用Portal将子组件渲染到父组件DOM 层次结构之外的DOM 节点中。建议portal创建一个新的DOM 节点

const Portal = ({ children }) => {
  // NOTE: it is assumed that the portal root is already present in the HTML file
  //       <div id="portal-root" />
  const portalRoot = document.getElementById("portal-root");
  return ReactDOM.createPortal(children, portalRoot);
};
Enter fullscreen mode Exit fullscreen mode

17.什么是 React Fiber?

React Fiber是ReactJS的一个概念,用于使系统渲染更快、更流畅。这是一次内部引擎改进,旨在使React更快、更“智能”。Fiber协调器已成为React 16及更高版本的默认协调器,它完全重写了React 的协调算法,以解决React中一些长期存在的问题

由于Fiber异步的,因此React可以:

  • 随着新更新的到来,暂停恢复重新启动组件的渲染工作
  • 重复使用以前完成的工作,甚至在不需要时中止它
  • 将工作分成多个部分,并根据重要性确定任务的优先级

这一变化使React摆脱了之前同步Stack Reconciler的限制,即任务无法被中断。此外,这一变化还允许React对渲染组件进行微调,确保最重要的更新尽快完成。

您是否正在摸不着头脑,不明白“和解”到底是什么?

令人费解

别担心,我们帮你搞定!在React中,协调 (reconciliation)是负责高效更新UI以响应组件状态或 props 变化的核心机制。它决定了将实际DOM转换为虚拟 DOM所表示的期望状态所需的最小操作集。

就这些啦,朋友们!🎉

如果你想要一份React Native面试题列表,请继续关注下一篇文章!

感谢阅读

需要一位顶级软件开发自由职业者来解决你的开发难题吗?在Upwork上联系我

想看看我正在做什么吗?查看我的个人网站GitHub

想联系我吗?请在LinkedIn上联系我

关注我的博客,每两周Medium上获取最新资讯

常问问题

这些是我收到的一些常见问题。希望这个常见问题解答部分能解决您的问题。

  1. 我是初学者,该如何学习前端 Web 开发?
    可以参考以下文章:

    1. 前端流行语
    2. 前端开发路线图
    3. 前端项目构想
    4. 从初学者过渡到中级前端开发人员
  2. 你能指导我吗?

    抱歉,我工作很忙,没时间指导任何人。

文章来源:https://dev.to/ruppysuppy/17-react-interview-questions-you-must-know-as-a-developer-in-2025-1o6f
PREV
用不到 15 行代码将你的网站变成跨平台桌面应用 Electron 是什么?为什么要使用 Electron?入门指南 构建应用 Electron 的缺点 使用 Electron 的项目 Smartsapp 感谢阅读
NEXT
如何在 AWS 上部署自己的网站