【前端校招面经】得物App 前端二面面经
之前的一面面经在这里:
- 自我介绍
- 你知道哪些前端构建工具,
Webpack
和Vite
各自的优势有哪些 - 列举
ES6
语法, 哪些你用得多 - 你刚才提到了
Promise
, 会手写 Promise 吗? - 列举你知道的数组的方法,
Array.prototype
forEach
和map
的区别- React 你知道有哪些
hooks
方法 useCallback
原理- 代码题: 用 React hooks 写一个计数器组件, 要求:
- 页面上有一个计数器, 一个开始按钮, 一个暂停按钮
- 点击开始按钮开始计数, 每秒计数器显示的数字 +1, 直到计数器到 20 后归零
- 点击暂停按钮会暂停数字的增长, 再次点击开始按钮会继续计数
- 计数器启动时, 开始按钮被禁止点击; 计数器未启动时, 暂停按钮被禁止点击
参考答案:
/* @file Counter.tsx */
import { Button } from 'antd';
import useCounter from './useCounter';
export default () => {
const { count, startCounter, pauseCounter, isRunning } = useCounter();
return (
<>
<p>count is: {count}s</p>
<Button onClick={startCounter} disabled={isRunning}>Start</Button>
<Button onClick={pauseCounter} disabled={!isRunning}>Pause</Button>
</>
);
};
/* @file configs.ts */
export const MAX_COUNT = 20;
/* @file useCounter.ts */
import { useState, useCallback } from 'react';
import { MAX_COUNT } from './configs';
export default function useCounter() {
const [count, setCount] = useState(0);
const [timer, setTimer] = useState<number | null>(null);
// 清空 timer, 用于用户点击暂停时或者计数器达到 MAX_COUNT 时复位
const clearTimer = useCallback(() => {
setTimer(prevTimer => {
clearInterval(prevTimer as number);
return null;
});
}, []);
// 点击开始按钮的响应
const startCounter = useCallback(() => {
const newTimer = setInterval(() => {
setCount(prevCount => {
const shouldReset = prevCount >= MAX_COUNT; // 判断计数是否已经到最大值
if (shouldReset) {
clearTimer();
return 0;
}
return prevCount + 1;
});
}, 1000);
setTimer(newTimer);
}, []);
return {
count, // 组件展示的计数
startCounter,
pauseCounter: clearTimer, // 点击暂停按钮的响应
isRunning: !!timer // 控制 2 个按钮的 disabled 状态
};
}
本题主要考察的点在于:
- 设计 20 秒复位时要考虑 hooks 带来的闭包问题, 因此在使用 setCount 时, 不能直接传值; 设计 setTimer 时同理
- 或者使用 useRef 替代 useState 来存储 timer, 因为 useRef 需通过 current 属性来访问被存储的目标值, 因此可避免闭包陷阱
#前端工程师精选面经合集##得物app#更新: 一月初时 HR 给意向, base: sh, hz 可选, 薪资相同