必须要会的 50 个 React 面试题
如果你是有抱负的前端,正在准备面试,可以把这 50 题当 React 复习提纲。JavaScript 工具在市场里站稳后,React 需求涨得很快;它虽只覆盖 MVC 的 View,却常拿来和 Angular、Meteor、Vue 比较。
截至原文写作时 GitHub 约有 1000 名贡献者。Virtual DOM 和可复用组件最吸引人。下面按基本知识、组件、Redux、路由分类,问与答全部保留。
JS 框架的趋势
一、基本知识
1. 区分 Real DOM 和 Virtual DOM
| Real DOM | Virtual DOM |
|---|---|
| 更新缓慢 | 更新更快 |
| 可以直接更新 HTML | 无法直接更新 HTML |
| 元素更新则创建新 DOM | 元素更新则更新 JSX |
| DOM 操作代价高 | DOM 操作更简单 |
| 更耗内存 | 内存消耗更少 |
2. 什么是 React?
-
Facebook 2011 年做的前端 JavaScript 库 -
基于组件,便于搭可复用 UI -
适合复杂、交互强的 Web 和移动 UI -
2015 年开源,社区很大
3. 有什么特点?
-
用虚拟 DOM而不是真实 DOM -
可以服务端渲染 -
遵循单向数据流或数据绑定
4. 主要优点
-
提升性能 -
客户端、服务器端都能用 -
JSX 让代码更好读 -
容易和 Meteor、Angular 等集成 -
UI 测试更好写
5. 限制
-
只是库,不是完整框架 -
体积大,需要时间吃透 -
新手可能觉得难 -
内联模板和 JSX 让编码显得复杂
6. 什么是 JSX?
JSX 是 JavaScript XML 的简写。React 用它把 JS 表现力和类 HTML 模板写在一起,文件更好懂,也有助于可靠性和性能。例如:
7. Virtual DOM 怎么工作?
Virtual DOM 是轻量 JS 对象,一开始是 real DOM 的副本:节点树,元素、属性和内容都是对象。render 从组件建树,再按数据模型变化(用户或系统)更新这棵树。三步:
-
底层数据一变,整份 UI 在 Virtual DOM 里重描述。 -
算新旧表示的差异。 -
只把真正变的补到 real DOM。
8. 为什么浏览器读不了 JSX?
浏览器只吃 JavaScript 对象。JSX 要先经 Babel 等转成 JS 对象再交给浏览器。
9. 和 ES5 比,ES6 写法有何不同?
require 与 import:
export 与 exports:
component 和 function:
props:
state:
10. React 和 Angular 有何不同?
| 主题 | React | Angular |
|---|---|---|
| 体系结构 | 只有 MVC 中的 View | 完整 MVC |
| 渲染 | 可以服务端渲染 | 客户端渲染 |
| DOM | virtual DOM | real DOM |
| 数据绑定 | 单向 | 双向 |
| 调试 | 编译时 | 运行时 |
| 作者 |
二、React 组件
11. 「在 React 中,一切都是组件」
组件是 UI 积木,把界面拆成独立可复用的小块,彼此不影响其余 UI。
12. render() 的目的
每个组件都要有 render(),返回 React 元素(对原生 DOM 的描述)。多个 HTML 元素必须包在一个封闭标签里。函数必须纯:同样输入得到同样输出。
13. 如何把两个或多个组件嵌进一个?
14. 什么是 Props?
Props 是 properties 的简写,只读、必须保持纯(不可变)。总是父传子,子不能把 prop 回传给父,从而维持单向数据流,常用来渲染动态数据。
15. 状态是什么?怎么用?
state 是组件的数据来源,应尽量简单。它决定呈现和行为,可变,用来做动态交互。通过 this.state 读取(不是函数调用)。
16. state 和 props
| 条件 | State | Props |
|---|---|---|
| 从父组件接收初始值 | Yes | Yes |
| 父组件可以改变值 | No | Yes |
| 在组件中设置默认值 | Yes | Yes |
| 在组件内部变化 | Yes | No |
| 设置子组件的初始值 | Yes | Yes |
| 在子组件内部更改 | No | Yes |
17. 如何更新状态?
用 this.setState():
18. 箭头函数
箭头函数(=>)是函数表达式的短写法,能绑住组件上下文(ES6 默认不自动绑定)。高阶函数里很好用。
19. 有状态 vs 无状态
| 有状态组件 | 无状态组件 |
|---|---|
| 内存中保存状态变化信息 | 计算内部状态(通常无自身 state) |
| 有权改变状态 | 无权改变状态 |
| 包含过去、现在、未来可能的状态 | 不包含这些变化情况 |
| 接收无状态组件的更新请求,再把 props 传下去 | 从有状态组件收 props,当作回调来用 |
20. 生命周期阶段
-
初始渲染:组件开始生命并进入 DOM -
更新:已在 DOM 中,仅当 prop 或 state 变才可能再渲染 -
卸载:销毁并从 DOM 删除
21. 生命周期方法
-
componentWillMount():渲染前,客户端和服务器都会执行 -
componentDidMount():仅第一次渲染后在客户端执行 -
componentWillReceiveProps():从父组件收到 props,下一次渲染前 -
shouldComponentUpdate():按条件返回 true/false 决定要不要更新;默认返回 true -
componentWillUpdate():写入 DOM 前 -
componentDidUpdate():渲染后立刻 -
componentWillUnmount():卸载后,用于清理
22. 事件是什么?
对悬停、点击、按键等的响应。类似 DOM 事件,但:
-
用驼峰命名,不是全小写 -
处理函数作为函数传递,不是字符串
事件参数带一组特定属性,只能在对应处理函数里访问。
23. 如何创建事件?
24. 合成事件
合成事件是包在浏览器原生事件外的跨浏览器包装,把不同浏览器行为收成一套 API,属性表现一致。
25. refs
Refs 是引用。用来存对某个 React 元素或组件的引用(render 返回的那个)。量 DOM 或给组件加命令式方法时用得上。
26. 什么时候用 Refs
-
管理焦点、选中文本或媒体播放 -
触发式动画 -
集成第三方 DOM 库
27. 如何模块化代码?
用 export / import 把组件写在不同文件:
28. 如何创建表单
形态像 HTML,但值在 state 里,只能 setState() 更新。提交由 JS 函数处理,函数能读到用户输入。
29. 受控 vs 非受控
| 受控组件 | 非受控组件 |
|---|---|
| 不自己维持状态 | 自己维持状态 |
| 数据由父组件控制 | 数据由 DOM 控制 |
| 通过 props 拿当前值,回调通知更改 | 用 Refs 拿当前值 |
30. 什么是 HOC?
高阶组件是复用组件逻辑的模式:一个组件里包另一个组件,接收子组件的动态能力,但不改、不复制输入组件的行为。可以看成「纯」组件。
31. HOC 能做什么?
-
代码复用,逻辑和引导抽象 -
渲染劫持 -
状态抽象和控制 -
Props 控制
32. 纯组件
纯(Pure)组件是最简单、最快的一种,可替换只有 render() 的组件,让代码更简单、性能更好。
33. key 为什么重要?
key 用来识别 Virtual DOM 元素和对应数据。React 靠它复用 DOM、只重排不整树重渲染,必须是唯一的数字或字符串,有利于性能。
三、React Redux
34. MVC 的主要问题
-
DOM 操作代价高 -
运行慢、效率低 -
浪费内存 -
循环依赖迫使组件模型围着 models 和 views 转
35. 解释 Flux
Flux 强制单向数据流。派生数据由拥有全部数据权限的中心 store 管,组件之间经它通信。应用里的数据更新只能发生在这里,更稳、运行时错误更少。
36. 什么是 Redux?
可预测的状态容器,管整个应用状态。用它写的应用更好测,跨环境行为一致。
37. 三个原则
-
单一事实来源:状态放在唯一 store 的对象树里,便于跟踪、调试 -
状态只读:只能 dispatch 一个描述变化的 action(普通对象) -
用纯函数改状态:reducer 的返回值只取决于参数
38. 「单一事实来源」
整个程序状态集中在 Store,组件都从这里收更新,变化可追踪。
39. Redux 的组件
-
Action:描述发生了什么 -
Reducer:决定状态怎么变 -
Store:整棵状态树 -
View:只展示 Store 给的数据
40. 数据如何流动?
41. 如何定义 Action?
必须有 type,表示动作种类,一般是字符串常量,也可加其他字段。由 Action Creator 函数创建:
42. Reducer 的作用
纯函数:接收旧 state 和 action,返回新 state。按 action.type 决定更新;不需要处理就返回原 state。
43. Store 的意义
JS 对象,保存状态,并提供读状态、dispatch、注册监听的方法。整棵树只有这一份,所以简单可预测。可把中间件传进 store 做日志等。所有操作经 reducer 得到新状态。
44. Redux 和 Flux
| Flux | Redux |
|---|---|
| Store 包含状态和更改逻辑 | Store 和更改逻辑分开 |
| 多个 Store | 只有一个 Store |
| Store 互不影响、平级 | 带分层 reducer 的单一 Store |
| 有单一调度器 | 没有调度器概念 |
| React 组件订阅 store | 容器组件是连接上的 |
| 状态可变 | 状态不可变 |
45. Redux 优点
-
结果可预测:永远只有一个真实来源 -
可维护:结构严、结果可预期 -
服务端渲染:把服务器上的 store 传给客户端,利于首屏 -
开发者工具:从 action 到 state 都能跟 -
社区:生态大 -
好测:多为小的纯函数 -
组织:代码怎么放有约定,团队更一致
四、React 路由
46. 什么是 React 路由?
建在 React 上的路由库,给应用加屏幕和流程,让 URL 和页面数据同步。用来做单页应用,API 相对简单。
47. 为什么 v4 要用 Switch?
<Switch> 包多条 <Route> 时,只渲染第一条匹配的路由,后面的不再比。适合「多条里只显示一条」的场景。
48. 为什么需要路由?
用户访问某 URL 时,若和某条 Route 的 path 匹配就进对应视图。所以要引入路由库,每条路由一个独特视图:
49. React Router 的优点
-
v4 的 API 也是组件化:根上是 Router,里面包 <Route>子路由 -
不必手设 history:把路由包在 Router 组件里即可 -
Web / Native / Core 分包,体积更小,风格接近,好切换
50. 和常规路由有何不同?
| 主题 | 常规路由 | React 路由 |
|---|---|---|
| 参与的页面 | 每个视图一个新文件 | 只涉及单个 HTML 页面 |
| URL 更改 | HTTP 请求要新 HTML | 只改 history |
| 体验 | 真的在不同页面间切 | 用户感觉在切页,实际还是 SPA |
希望这套题能帮你准备面试。
作者:前端先锋
链接:https://juejin.im/post/6844903806715559943
一句话总结:面试 React 先分清 Virtual DOM、props/state、生命周期和受控组件,再用 Redux 的单向数据流和 React Router 的 Switch 把应用串起来。
转载请注明来源:必须要会的 50 个 React 面试题











