作为前端开发者,React 是现代前端面试中的核心考点之一。本文将围绕 React 中的四大高频面试题展开:JSX 的本质、Key 的作用与原理、Babel 在 React 中的角色、受控组件与非受控组件的区别,帮助你从原理到实践全面掌握这些核心知识点。
一、JSX 是什么?它的本质是什么?
面试常问:
- JSX 和 HTML 有什么区别?
- JSX 是如何被 React 处理的?
- 为什么不能直接在浏览器中运行 JSX?
核心知识点:
JSX(JavaScript XML)是 React 提供的一种语法扩展,允许你在 JavaScript 中编写类似 HTML 的结构。它并不是 HTML,也不是字符串,而是一种声明式 UI 编写方式,最终会被编译为标准的 JavaScript 对象。
原理详解:
JSX 是一种语法糖,其本质是调用 React.createElement() 方法来创建 React 元素对象。这个过程由 Babel 完成,最终生成的是虚拟 DOM(Virtual DOM)结构。
示例代码:
// JSX 写法
const element = <h1>Hello, world!</h1>;
// Babel 编译后
const element = React.createElement('h1', null, 'Hello, world!');
编译后结构:
{
type: 'h1',
props: {
children: 'Hello, world!'
}
}
小结:
JSX 不是 HTML,也不是字符串,它是 React 的语法糖,本质是调用
React.createElement()创建虚拟 DOM。最终由 Babel 转换为浏览器可执行的 JavaScript。
二、Key 的作用及其原理
面试常问:
- 为什么列表渲染时必须加 key?
- key 的作用是什么?为什么不能用 index 作为 key?
- key 是如何影响 React 的 diff 算法的?
核心知识点:
在 React 中,key 是一个特殊的属性,用于帮助 React 识别哪些元素被添加、删除或修改。它在列表渲染(如 map)中尤为重要,能显著提升性能。
原理详解:
React 的 Reconciliation(协调)算法通过 key 来决定如何高效更新 DOM。当 key 改变时,React 会认为这是一个新的元素,从而触发卸载和重新渲染。
- 有 key: React 能精准复用、移动、删除 DOM 节点。
- 无 key 或 key 不唯一: React 只能按顺序对比,可能导致不必要的 DOM 操作。
- 不推荐使用 index 作为 key: 尤其在可变列表中,会导致状态混乱(如 input 输入框的值错位)。
示例代码:
const list = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
];
// 推荐写法:使用唯一标识作为 key
<ul>
{list.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
小结:
key 是 React 列表渲染中必不可少的属性,用于提高 diff 算法的效率。推荐使用唯一 ID 作为 key,避免使用 index。
三、Babel 在 React 项目中的作用
面试常问:
- Babel 在 React 项目中起什么作用?
- JSX 为什么能被浏览器识别?
- React 项目中常用的 Babel 插件有哪些?
核心知识点:
Babel 是一个 JavaScript 编译器,用于将 ES6+ 语法和 JSX 转换为向后兼容的 ES5 代码,确保代码能在各种浏览器中运行。
工作流程:
- 开发者编写 JSX 和 ES6+ 代码。
- Babel 使用插件(如
@babel/preset-react)将 JSX 转换为React.createElement()调用。 - 最终输出标准 JavaScript,供浏览器执行。
示例代码:
// JSX 写法
const element = <div className="box">内容</div>;
// Babel 编译后
const element = React.createElement(
'div',
{ className: 'box' },
'内容'
);
常见 Babel 插件:
@babel/core:Babel 核心库@babel/cli:命令行工具@babel/preset-env:转换 ES6+ 语法@babel/preset-react:支持 JSX 和 React 相关语法
小结:
Babel 是 React 项目中不可或缺的工具,它将 JSX 和现代 JavaScript 转换为浏览器兼容的代码,是 React 开发流程中的关键一环。
四、受控组件与非受控组件的区别
面试常问:
- 什么是受控组件?什么是非受控组件?
- 为什么推荐使用受控组件?
- 什么时候适合使用非受控组件?
核心知识点:
- 受控组件(Controlled Component): 表单数据由 React 的 state 控制,通过
onChange同步更新。 - 非受控组件(Uncontrolled Component): 表单数据由 DOM 自身管理,通常通过
ref获取值。
使用场景对比:
| 类型 | 数据来源 | 更新方式 | 推荐场景 |
|---|---|---|---|
| 受控组件 | React state | onChange | 表单校验、联动、复杂交互 |
| 非受控组件 | DOM | ref | 简单表单、一次性获取值、性能敏感场景 |
示例代码:
受控组件:
function App() {
const [value, setValue] = useState('');
return (
<input
value={value}
onChange={e => setValue(e.target.value)}
/>
);
}
非受控组件:
function App() {
const inputRef = useRef();
const handleClick = () => {
console.log(inputRef.current.value);
};
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>提交</button>
</>
);
}
小结:
受控组件通过 state 控制表单数据,更符合 React 的数据流理念;非受控组件通过 ref 获取 DOM 值,适合简单场景或性能优化场景。
结语
以上四个问题(JSX、Key 原理、Babel 编译、受控/非受控组件)是 React 面试中出现频率极高的考点。理解其背后的原理和使用方式,不仅能帮助你在面试中脱颖而出,也能提升你在实际项目中的开发效率和代码质量。
如果你喜欢这篇文章,欢迎点赞、收藏、分享给更多开发者朋友。如果你有其他 React 面试相关问题,也欢迎留言交流!