{items.map((item, index) => (
handleClick(item)}>
{item.name}
))}
);
};
```
A. 使用 item.id 作为 key 而非 index
B. 使用虚拟滚动
C. 使用 useMemo 包裹 items
D. onClick 使用 useCallback
**正确答案:** ABD
**作答答案:** ABD ✅
> [!TIP] 🔑 为什么不选 C?
> `useMemo` 包裹 items 并不能直接优化列表渲染性能——items 来自 props,其变化由父组件决定。关键在于 **key 稳定性**(A)、**渲染策略**(B)和**事件处理器引用稳定**(D)。
---
#### 4. useEffect + 键盘事件监听
【多选题】关于下面代码说法正确的是?(4分)
```js
useEffect(() => {
const onKeyDown = (e) => {
const userAgent = navigator.userAgent;
const isMac = /Macintosh|MacIntel|MacPPC|Mac68K/.test(userAgent);
if ((isMac && e.metaKey && e.key.toLowerCase() === 'k') ||
(!isMac && e.ctrlKey && e.key.toLowerCase() === 'k')) {
e.preventDefault();
inputRef.current?.focus();
}
};
window.addEventListener('keydown', onKeyDown);
return () => window.removeEventListener('keydown', onKeyDown);
}, []);
```
A. 在 Mac 设备上按下 Command+K 键,或在非 Mac 设备上按下 Ctrl+K 键时,让 inputRef 对应的输入框获取焦点
B. 该 useEffect 仅在组件挂载时执行一次,因为其依赖数组为空
C. 清理函数会在组件卸载时执行,用于移除添加的 keydown 事件监听,避免内存泄漏
D. 清理函数的主要作用是阻止键盘事件的默认行为
**正确答案:** ABC
**作答答案:** ABCD
> [!FAIL] 💔 易错点
> **D 是错误的**:`e.preventDefault()` 阻止的是浏览器默认行为(如 Cmd+K 的搜索框聚焦),而清理函数 `removeEventListener` 的作用是**移除事件监听器本身**,二者职责完全不同。
---
#### 5. GIF 埋点 vs AJAX
【多选题】相比较 AJAX,有些公司前端监控都喜欢用 GIF 做埋点上报,以下哪些是 GIF 的优势?(4分)
```js
// GIF 方案
const report = (data) => {
const img = new Image();
img.src = `https://log.example.com/track.gif?data=${encodeURIComponent(JSON.stringify(data))}`;
};
// Ajax 方案
const report = (data) => {
fetch('https://log.example.com/track', {
method: 'POST',
body: JSON.stringify(data)
});
};
```
A. GIF 请求不需要等待响应,发送即走
B. GIF 可以跨域,不受 CORS 限制
C. 页面卸载时 GIF 请求不会被取消
D. GIF 体积最小(1x1 像素)
**正确答案:** ABD
**作答答案:** ABD ✅
> [!NOTE] ℹ️ 为什么不用 C?
> 页面卸载(unload)时,`navigator.sendBeacon()` 可以保证请求发送,但普通 `