你准备好迎接 2025 年的前端面试了吗? 无论你是想加入 FAANG、热门初创公司还是产品公司,React依然是 UI 领域的霸主 。为了帮助你在下一次面试中脱颖而出,我整理了40 个顶尖科技公司今年会问的React 问题,并附有清晰的答案
40 个 React 面试题及答案
1.❓什么是 React?
这通常是 React 面试中的第一个问题。它有助于衡量应聘者是否理解 React 的用途,以及它与其他框架或库的区别。
答:
React 是由Meta(前身为 Facebook)开发的JavaScript 库,用于构建用户界面,尤其适用于需要快速、交互式用户体验的单页应用程序。它是声明式的、基于组件的,并使用虚拟 DOM来优化渲染。您无需直接操作 DOM,而是描述 UI 的外观,React 会负责高效地更新它。
2. 什么是 JSX?
JSX 是编写 React 组件的核心。面试官问这个问题是为了考察你是否理解 React 如何融合 JavaScript 和 HTML。
答:
JSX(JavaScript XML)是JavaScript 的语法扩展,允许你在 JavaScript 中编写类似 HTML 的代码。它使你的组件结构更具可读性和表现力。在底层,JSX 被转换为React.createElement()生成虚拟 DOM 元素的调用。例如:
const greeting = <h1>Hello, world!</h1>;
3. 什么是组件?
组件是 React 的基础。如果不深入理解组件,就无法构建 React 应用。
答: React 中的组件是一个
可复用的、独立的 UI 部分,它定义了屏幕上应该显示的内容。组件分为函数式组件(更简单,是带有 hooks 的现代标准)和类组件(虽然比较老,但仍在使用)。组件接收props并管理状态以渲染动态内容。
4. 函数式组件和类组件有什么区别?
了解从类到功能组件的演变以及钩子的作用在现代 React 中至关重要。
回答:
函数组件是返回 JSX 的 JavaScript 函数。它们最初是无状态的,但从 React 16.8 开始,它们可以使用hooks来管理状态和副作用。
类组件使用 ES6 类,可以访问生命周期方法(如)
componentDidMount,并通过管理状态this.state。
由于语法更简单、性能更好、可读性更强,函数式组件现在更受青睐。
5. React 中的 props 是什么?
Props 是组件通信的必备元素。这道题考察你对单向数据流的理解。
答:
Props ( properties的缩写)是从父组件传递给子组件的只读输入。它们使组件变得动态且可重用。Props 支持单向数据绑定,这意味着数据从父组件流向子组件。
例子:
<MyComponent name="Alice" />
在MyComponent,props.name将是"Alice"。
6. ♂️ React 中的钩子是什么?
Hooks 改变了我们编写 React 应用的方式。这个问题揭示了你对现代 React 开发的熟悉程度。
答:
Hook是一种特殊的函数,它让你无需使用类就能“钩住” React 的特性,例如state、context和生命周期方法。Hook 在 React 16.8 中引入,它使函数组件更加强大且简洁。例如useState,useEffect、useContext和自定义 Hook。
7. 做什么useState?
状态是交互的核心。本题考察你是否能够使用钩子管理本地组件状态。
答案:useState是React hooks ,用于在功能组件中声明一段状态。
例子:
const [count, setCount] = useState(0);
count是当前状态值。setCount是更新该值的函数。
当状态改变时,它会重新渲染组件。
8. 如何useEffect工作?
管理 React 中的副作用(例如数据获取)至关重要。useEffect取代了几个类生命周期方法。
答案:useEffect在组件渲染后运行。它用于诸如获取数据、更新 DOM或订阅服务之类的副作用。
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
依赖数组([count])告诉 React 仅当发生变化时才重新运行效果count。
9. useContext用于什么?
它简化了深度嵌套组件之间的数据共享,无需 prop-drilling。
答案:是一个钩子,它允许您直接在功能组件中useContext使用来自React Context的值。
例子:
const value = useContext(MyContext);
这样就避免了在组件树的每一层手动传递 props。这对于主题切换、用户身份验证等操作非常有用。
useEffect10. ♂️和 有什么区别useLayoutEffect?
选择错误可能会导致性能问题或闪烁。这道题考察你对渲染的深度理解。
回答:
useEffect在 paint 之后运行,这意味着它不会阻塞浏览器。useLayoutEffect在所有 DOM 变化之后但在浏览器重新绘制之前同步运行。
用于DOM 测量useLayoutEffect或同步更新。否则,最好避免阻塞 UI。useEffect
11.⏳React 组件生命周期的主要阶段是什么?
了解生命周期有助于您管理何时加载数据、清理订阅或有效地触发重新渲染。
答:
React 类组件经历三个主要生命周期阶段:
正在创建挂载
constructor组件并将其插入到 DOM 中( ,componentDidMount)。由于 props 或 state 的变化,更新组件正在重新渲染(
shouldComponentUpdate,componentDidUpdate)。卸载组件正在从 DOM 中移除(
componentWillUnmount)。
使用钩子,您可以使用来处理生命周期逻辑useEffect。
12. 什么是虚拟 DOM?
这就是 React 性能背后的秘密。了解这一点,就意味着你理解了 React 如何优化 UI 渲染。
答:
虚拟DOM是真实 DOM 的轻量级 JavaScript 表示。当状态发生变化时,React 会:
创建虚拟 DOM。
将其与以前的版本进行比较(使用差异算法)。
仅对实际 DOM 应用必要的更改。
与直接操作 DOM 相比,这个过程快速而高效。
13. React 中的协调是什么?
这就是 React 更新 DOM 的方式。它与性能和渲染行为紧密相关。
答: React 会将
新的虚拟 DOM 树与之前的虚拟 DOM 树进行比较,并确定所需的最小更改次数。它使用diffing 算法和基于键的列表优化,以便有效地仅更新已更改的内容。
key14. React 列表的 用途是什么?
这是一个小细节,如果理解错误,可能会导致错误。这对于列表渲染至关重要。
答案:
Akey是一个特殊的字符串属性,用于唯一标识列表中的元素。React 在协调期间使用它来跟踪哪些项目被更改、添加或删除。
{items.map(item => <li key={item.id}>{item.name}</li>)}
当列表可以改变时,避免使用索引作为键。
15. 受控组件和非受控组件有什么区别?
表单无处不在。这测试你是否理解如何在 React 中正确管理输入状态。
回答:
受控组件使用React 状态
value来管理表单输入。您可以使用和 来控制值onChange。不受控制的组件让DOM 处理输入状态,用于
ref访问值。
16. ☣ 什么是道具钻孔?如何避免它?
这个问题会随着应用程序的复杂性而增长。他们想知道你是否能够构建可扩展的组件。
答案:当你将 props 传递到多个级别的组件以到达深层嵌套的子组件时,就会发生
Prop 钻探。
为了避免这种情况:
使用React Context
使用状态管理库,例如 Redux、Zustand 或 Recoil
创建组件组合策略
17. React 中的状态提升是什么意思?
这是共享状态的常见模式。它展示了你对 React 单向数据流的掌握。
答:
状态提升意味着将状态移动到需要共享状态的组件的最近公共祖先。这避免了重复并确保了数据的一致性。
示例:
将selectedItem状态从组件移出Child1并Child2移入Parent组件,并通过 props 传递它。
18. 什么是高阶组件(HOC)?
HOC 是 React 中一个强大的设计模式。许多库都在底层使用它们。
答案:高阶组件
是一个接受组件并返回具有附加道具或逻辑的新组件的函数。
const withLogger = (Component) => (props) => {
console.log('Rendering:', Component.name);
return <Component {...props} />;
};
它们用于代码重用、身份验证、主题化等。
19. 什么是渲染道具?
此模式允许灵活的代码共享。它是可复用组件设计的关键概念。
答案:渲染道具
是一种技术,其中组件的子项是一个返回 JSX 的函数。
<MyComponent render={(data) => <p>{data}</p>} />
它允许您以可定制的方式将行为和逻辑传递给子项,类似于 HOC。
20.⚛️什么是 React Fiber?
这表明对 React 内部工作原理有更深入的了解,尤其是性能优化。
答:
React Fiber是React 中新的协调引擎(自 v16 起)。它支持:
增量渲染
更新的优先级
错误边界
并发支持
它将工作分解成多个部分,并将渲染分散到多个帧上,以获得更流畅的体验。
21. 如何优化 React 应用的性能?
顶尖科技公司青睐注重性能的工程师。这表明你有能力构建可扩展的应用程序。
答:
您可以通过多种方式优化性能:
使用React.memo来记忆功能组件。
使用
useMemo()和useCallback()避免不必要的计算和重新创建。使用React.lazy和Suspense拆分代码。
尽可能保持组件状态本地化。
避免深钻孔或不必要的渲染。
利用shouldComponentUpdate(类)或React.PureComponent。
22. 什么是 React.memo 以及何时应该使用它?
这是一种通过防止重新渲染来提高性能的简单方法。
答案:React.memo是一个记忆组件的高阶组件,这意味着只有当它的 props 发生变化时它才会重新渲染。
const MemoizedComponent = React.memo(MyComponent);
将其用于为相同道具呈现相同输出的纯功能组件。
23. ⚖ useMemo 和 useCallback 有什么区别?
这些技巧很强大,但经常被混淆。面试官想知道你是否知道何时以及为何使用它们。
回答:
useMemo(fn, deps)返回一个记忆值。useCallback(fn, deps)返回一个记忆函数。
useMemo当您有昂贵的计算时,以及useCallback将函数传递给优化的子项(例如包装在中的子项React.memo)时使用。
24. useEffect 中的清理函数是什么?
副作用可能会变得混乱。这表明您可以负责任地管理内存和订阅。
答案:清理函数
在组件卸载之前或效果重新运行之前运行。
useEffect(() => {
const timer = setTimeout(() => {}, 1000);
return () => clearTimeout(timer);
}, []);
这对于清理事件监听器、订阅或超时至关重要。
25. 什么是 React.StrictMode?
它是一款开发者工具,可以帮助你编写简洁、面向未来的代码。面试官会用它考察当前的最佳实践。
答:<React.StrictMode>它是一个用于在开发过程中突出显示应用中潜在问题的工具。它:
检测不安全的生命周期方法
关于使用旧版 API 的警告
检测意外的副作用
它不会影响生产版本并像这样包装您的应用程序:
<React.StrictMode>
<App />
</React.StrictMode>
26. 什么是 React Router?
现实世界中的应用需要多个页面。React Router 是最佳解决方案。
答:
React Router 是React 的标准路由库。它允许你在单页应用中处理导航、URL 参数和动态路由。
关键组件:
<BrowserRouter>:包装你的应用程序<Route>:根据路径渲染组件<Link>:在路线之间导航useParams,useNavigate: 动态路由钩子
27. 如何在 React Router 中处理重定向?
路由控制至关重要,尤其是在登录或表单提交等操作之后。
答案:
在 React Router v6 中:
import { Navigate } from 'react-router-dom';
return <Navigate to="/dashboard" />;
或者使用useNavigate:
const navigate = useNavigate();
navigate('/login');
28.✍️ 如何在 React 中处理表单?
表单 = 真实世界的交互。你的答案展示了你如何构建用户输入和验证。
答:
您可以使用以下方式管理表单:
受控组件(
value,onChange)useState用于输入字段使用Formik、React Hook Form等库或手动逻辑进行验证
onSubmit通过提交处理程序<form>
例子:
const [name, setName] = useState('');
<form onSubmit={handleSubmit}>
<input value={name} onChange={(e) => setName(e.target.value)} />
</form>
29. 什么是 React Hook Form?
它是一种轻松处理复杂表格的流行工具。
答:
React Hook Form是一个使用非受控组件、性能优先的表单库。它与Yup等验证库无缝集成。
const { register, handleSubmit } = useForm();
<input {...register("email")} />
与其他替代方案相比,它提供了更好的性能和更少的样板。
30. 什么是自定义钩子?
自定义钩子 = DRY 代码。这道题考察你是否编写了可复用的逻辑。
答:
自定义钩子是使用内部的 React 钩子来封装和跨组件重用逻辑的函数。
function useAuth() {
const [user, setUser] = useState(null);
// login/logout logic
return { user, login, logout };
}
以...为前缀,use这样 React 就知道它遵循钩子规则。
31. 什么是 Redux?
它是一款功能强大且广泛使用的状态管理解决方案。即使您不使用它,了解它也是关键。
答:
Redux是JavaScript 应用程序的可预测状态容器。它使用单个全局 store、actions和reducer来管理和更新应用程序状态。
React使用和通过React-Redux库连接到 Redux 。useSelectoruseDispatch
32. 什么是 Redux 流程?
这表明您是否真正了解 Redux 中的状态流动方式。
回答:
UI 调度一个动作
Reducer接收当前状态 + 动作并返回新状态
商店更新
UI 使用新状态重新渲染
33.⚡ 什么是 Context API 以及何时应该在 Redux 上使用它?
React 也有内置工具。这会检查你是否选择了正确的工具。
答:
Context API提供了一种无需 props即可沿组件树向下传递数据的方法。在以下情况下使用它:
您需要轻量级的状态管理
状态不是很复杂
你避免为主题、用户或语言环境等小用例添加 Redux
34. Redux 中的 Reducer 是什么?
Reducer 是 Redux 的核心。如果不理解它们,就无法正确使用 Redux。
答案:
Reducer是一个纯函数,它接受当前状态和动作,并返回新状态。
function counterReducer(state = 0, action) {
switch (action.type) {
case 'INCREMENT': return state + 1;
default: return state;
}
}
Reducer 必须是纯净的:没有副作用。
35. ⚠ Redux 中的中间件是什么?
这表明您是否了解异步操作和副作用。
答: Redux 中的
中间件是位于调度 action和reducer之间的函数。它通常用于:
日志记录
崩溃报告
异步操作(使用 Redux Thunk 或 Redux Saga)
36. React 中的片段是什么?
它是一个小巧但优雅的工具,可以避免不必要的 DOM 元素。
答案:
React Fragments(<></>)让您返回多个元素而无需将它们包装在中div。
<>
<h1>Title</h1>
<p>Description</p>
</>
它改进了语义 HTML并避免了过多的嵌套。
37. 什么是错误边界?
应用程序崩溃。这将测试你是否知道如何正确捕获 React 运行时错误。
答:
错误边界是React 组件,它在渲染期间捕获其子组件中的 JavaScript 错误并显示后备 UI。
只有类组件可以使用以下方式定义错误边界:
componentDidCatch()static getDerivedStateFromError()
38. 如何测试 React 组件?
质量 = 测试覆盖率。你很可能会在使用测试的团队中工作。
答案:
使用:
Jest:测试框架
React 测试库:像用户一样测试 UI
酶:较旧,但仍在使用
常见做法:
测试渲染
模拟用户交互
断言输出和状态
39. 什么是协调和差异?
渲染效率很重要。这表明你了解 React 如何更新 DOM。
答: React使用差异算法将之前的虚拟 DOM 与新的虚拟 DOM进行比较,从而实现 DOM 更新的协调
(React Reconciliation)方式。它仅更新已更改的内容,以获得最佳性能。
40.❌React 中常见的错误有哪些?
优秀的开发人员不仅知道如何去做,他们还知道什么不该做。
回答:
直接修改状态,而不是使用
setState或setXkey像列表中一样使用索引忘记清理
useEffect太多不必要的重新渲染
不使用表单的受控组件
当上下文/状态管理更好时进行深度 prop 钻探
最后的想法
恭喜!你刚刚回顾了2025 年顶尖科技公司会提出的40道 React 面试题。

