🚀 React 面试 20 题精选:基础 + 实战 + 代码解析

349 阅读5分钟

4.webp

作为 React 开发者,深入理解 React 的关键概念对于拿下面试、写出高质量代码都至关重要。本文精心整理了 20 个高频面试问题,涵盖了从基础原理、核心 API 到性能优化与测试的各个方面。

💡 建议:在查看答案前,先自己尝试回答,再对照解析,能加深理解效果!


📚 目录

  1. 什么是 React?它的优势?
  2. 虚拟 DOM 是什么?如何工作?
  3. React 如何处理更新和渲染?
  4. React 中组件的概念
  5. 什么是 JSX?为什么使用?
  6. state 和 props 的区别
  7. 受控组件 vs 非受控组件
  8. 什么是 Redux?如何与 React 配合?
  9. 什么是高阶组件 (HOC)?
  10. 服务端渲染 vs 客户端渲染
  11. 什么是 React Hooks?
  12. React 中如何管理状态?
  13. useEffect 是怎么工作的?
  14. 再谈服务端渲染(SSR)
  15. React 中的事件处理机制
  16. 什么是 React Context?
  17. React 如何实现路由?
  18. 性能优化有哪些实践?
  19. React 测试:框架与方式
  20. React 中的异步数据加载

1. 什么是 React?它的优势?

React 是一个构建用户界面的 JavaScript 库,专注于 View 层。它允许开发者构建可组合的组件,高效渲染视图。

核心优势:

  • 🧩 组件化开发
  • ⚡ 虚拟 DOM 提高性能
  • 🔁 单向数据流,易于调试
  • 📦 丰富生态(如 Redux、React Router)

2. 什么是虚拟 DOM?它是如何工作的?

虚拟 DOM(Virtual DOM)是内存中的一种 JS 表示,它避免了频繁的 DOM 操作。

工作流程:

  1. 修改 state/props → 生成新的虚拟 DOM
  2. 旧虚拟 DOM vs 新虚拟 DOM 进行 diff
  3. React 根据变化更新真实 DOM(最小 patch)

3. React 如何更新和渲染组件?

  • 使用 setStateuseState 更新状态
  • 触发 Virtual DOM 重建
  • 执行 diff → 最小化 DOM 操作(协调阶段)
  • 更新 DOM & 触发 render

4. 组件是什么?如何定义?

组件是一个独立的 UI 单位,可以复用。React 支持:

// 函数组件
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

// 类组件
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

5. 什么是 JSX?为什么使用?

JSX 是 JavaScript 的语法扩展,让我们在代码中写 HTML。

const element = <h1 className="greeting">Hello, world!</h1>;

它最终会被 Babel 转换为:

React.createElement('h1', { className: 'greeting' }, 'Hello, world!');

6. props vs state 区别

propsstate
外部传入,只读组件内部可变数据
父组件传子组件组件内部自己管理
不可修改通过 setState 修改

7. 受控组件 vs 非受控组件

// 受控组件
<input value={value} onChange={e => setValue(e.target.value)} />

// 非受控组件(使用 ref)
<input ref={inputRef} />
  • ✅ 受控组件优点:统一管理表单值,更易做校验和联动。
  • ❌ 非受控组件依赖原生 DOM 操作。

8. 什么是 Redux?如何与 React 配合?

Redux 是一个状态容器,三大原则:

  1. 单一状态树
  2. 状态只读(不可直接修改)
  3. 使用纯函数 reducer 更新状态

与 React 配合使用:

import { Provider } from 'react-redux';

<Provider store={store}>
  <App />
</Provider>

组件中通过 useSelectoruseDispatch 获取状态和派发 action。


9. 什么是高阶组件 (HOC)?

高阶组件是一种模式:函数接收组件,返回新组件

function withAuth(Component) {
  return function Enhanced(props) {
    return props.loggedIn ? <Component {...props} /> : <Login />;
  }
}

用途:抽离逻辑、增强功能、权限处理、复用等。


10. SSR vs CSR 有什么区别?

特性SSR(服务端渲染)CSR(客户端渲染)
首屏速度慢(需要 JS 执行)
SEO好(直接返回 HTML)差(依赖爬虫执行 JS)
动态交互首次加载后通过 hydration完全在客户端渲染

11. 什么是 Hooks?为什么重要?

Hooks 是函数组件中的特性,提供状态、生命周期、副作用等功能。

常用 Hook:

const [count, setCount] = useState(0);

useEffect(() => {
  console.log('副作用');
}, [count]);

12. React 如何管理状态?

  • 使用 useState 管理局部状态
  • 使用 useReducer 管理复杂状态逻辑
  • 使用 context + reducer 共享全局状态
  • 使用 Redux / Zustand / Jotai 等状态管理库扩展能力

13. useEffect 是怎么工作的?

useEffect(() => {
  // 副作用逻辑,如请求、订阅
  return () => {
    // 清理逻辑
  };
}, [dependencies]);
  • 会在组件渲染后执行
  • 依赖数组为空,只在首次运行
  • 可以处理定时器、API、DOM 操作等

14. SSR 再解释(深入)

React SSR 的核心 API 是 ReactDOMServer.renderToString()

用途:

  • SEO 要求高的应用(如博客、电商)
  • 提高首屏加载性能
  • 常见框架:Next.js、Remix

15. React 中如何处理事件?

<button onClick={handleClick}>Click Me</button>

function handleClick(event) {
  console.log(event.target);
}
  • 使用驼峰式命名(如 onClick
  • 合成事件系统(跨浏览器兼容)
  • 可使用 e.preventDefault() 等标准方法

16. 什么是 Context?

Context 用于“跨组件传值”,避免 props 层层传递。

const ThemeContext = createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div className={`theme-${theme}`}>主题内容</div>;
}

17. React 路由怎么实现?

使用 React Router

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/about" element={<About />} />
  </Routes>
</BrowserRouter>
  • 支持嵌套路由、动态路由、懒加载等

18. 性能优化建议有哪些?

  • 使用 React.memo 避免不必要渲染
  • 合理拆分组件
  • 使用懒加载(React.lazy
  • 利用 key 优化列表渲染
  • 减少匿名函数创建

19. 如何测试 React 应用?

主流测试工具:

  • Jest:单元测试框架(官方推荐)
  • React Testing Library:组件行为测试(更偏用户体验)
  • Cypress / Playwright:端到端测试(E2E)

示例:

test('按钮点击次数增加', () => {
  render(<Counter />);
  fireEvent.click(screen.getByText('Add'));
  expect(screen.getByText('Count: 1')).toBeInTheDocument();
});

20. 如何处理异步请求?

const [data, setData] = useState(null);

useEffect(() => {
  fetch('/api/data')
    .then(res => res.json())
    .then(setData)
    .catch(console.error);
}, []);

实践建议:使用 axios + try/catch 更好控制错误,结合 loading/error 状态增强 UX。


✅ 总结

这份 20 个问题的清单涵盖了 React 面试的主干内容。掌握它们将帮助你:

  • 💼 面试自信回答
  • 🧠 加深对 React 底层机制的理解
  • 📈 写出更高质量、更稳定的代码

如果你想继续深入,建议关注:

  • 官方文档(react.dev
  • 框架实践(Next.js、Remix)
  • 实战项目与测试驱动开发