各位真大佬,鄙人最近在面试 React 初 /中级,请问一下这个问题是否合理?
// 按钮挂载后,10 秒点击按钮 N 次,打印的效果? const [count, setCount] = useState(0) useEffect(() => { setTimeout(() => { console.log(count); }, 10 * 1000 ) }, []); <button OnClick={() => setCount(count + 1)} />
个人感觉这个问题还是会考察候选人对 React 、React 的 useEffect 理解,不知道各位大佬怎么看?
1 uen 2022-07-08 11:06:03 +08:00 useEffect 依赖参数传空数组只会组件初始化的时候渲染一次 |
2 Leviathann 2022-07-08 11:20:18 +08:00 可以把 考察基本的闭包用法 |
![]() | 3 cyrbuzz 2022-07-08 11:20:33 +08:00 ![]() 得给 button 加点文字,不然不好点(逃~)。 |
4 yuningWang8 2022-07-08 15:12:22 +08:00 useEffect 回调执行的是当前状态的缓存。这个代码不能打印出最新的 count 。 |
5 dcsuibian 2022-07-08 15:19:10 +08:00 还行,关键词:React 闭包陷阱 |
![]() | 7 ethusdt 2022-07-08 16:08:50 +08:00 不错的, 可以筛选掉一些只会用 react 的人 |
![]() | 10 zhuangzhuang1988 2022-07-08 16:23:58 +08:00 太魔法了. |
11 Leviathann 2022-07-08 16:28:21 +08:00 @zhuangzhuang1988 这个就是 hook 的基石,结合 memo 、callback 啥的,搞到后面越写越复杂,所以很多人都很喜欢 solidjs 的设计 |
![]() | 12 ragnaroks 2022-07-08 16:39:36 +08:00 合理 |
![]() | 14 ragnaroks 2022-07-08 16:41:40 +08:00 ![]() setTimeout 、依赖列表、useEffect 清理、闭包捕获的变量的值,都是常见可能失误的地方 |
![]() | 15 mameng 2022-07-08 16:51:20 +08:00 结果是 0 , [] 里面为空只有第一次渲染,更新不渲染 |
16 gdrk 2022-07-08 17:00:05 +08:00 我就说看着眼熟,dan 这篇[博文] ( https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/)算是完整的讲解了这题的几个关键点。感觉面中级这题是不是简单了点, 毕竟 dan 的这篇文章还挺入门的 |
17 gdrk 2022-07-08 17:03:48 +08:00 ![]() 我这 markdown 真的是用的稀烂... [博文]( https://overreacted.io/zh-hans/a-complete-guide-to-useeffect) |
![]() | 19 yuthelloworld 2022-07-08 17:20:24 +08:00 []里没有监测的变量。所以不会打印吧 |
![]() | 21 darkengine 2022-07-08 17:30:21 +08:00 短短几行代码,包含了很多坑,用来考核挺好的 |
![]() | 22 XTTX 2022-07-08 17:34:12 +08:00 除非想读十秒前的值, 不然需要用 ref.current 更新到最新的。 我觉得挺经典的一道题。 |
![]() | 23 yuuko 2022-07-08 18:33:41 +08:00 React hook 的最大缺点就是对用户来说不直观,心智负担不小,所以还是 solidjs 更胜一筹 |
![]() | 24 h1104350235 2022-07-08 18:35:04 +08:00 有大佬解释下吗 |
![]() | 25 wenbinwu 2022-07-08 19:02:11 +08:00 如果有公司让你看代码说结果,就不用去这种公司了 |
26 dtdths1 2022-07-08 19:23:09 +08:00 但凡是写过 react hooks 的,应该都知道吧 |
![]() | 27 damngoto 2022-07-08 19:44:10 +08:00 @h1104350235 装个 EsLint 插件就不会犯错了。依赖加上去。 useEffect(() => { setTimeout(() => { console.log(count); }, 10 * 1000); }, [count]); |
![]() | 29 rabbbit 2022-07-08 19:56:42 +08:00 ![]() useEffect(() => {}, []) 只会在挂载时调用, 所以打出 来的都是 0 解决办法是使用 useRef 感觉 hook 限制顺序还是写着难受, 带着镣铐的舞蹈 |
![]() | 30 zhouyg 2022-07-08 22:40:09 +08:00 这个面试题可以 |
![]() | 31 mufeng 2022-07-09 00:38:21 +08:00 @rabbbit useRef 不会 re-render ,这个题还可以考察一下 re-render 怎么处理,useCallback 使用 |
![]() | 32 ericls 2022-07-09 00:43:45 +08:00 via iPhone 非常不合理 代码是给电脑跑的 |
![]() | 33 mara1 2022-07-09 01:22:04 +08:00 我不想做这种题,但遇到的面试许多这样的,接受不能改变的,改变能改变的。 我改变自己,我选择转行。 |
![]() | 34 Exuanbo 2022-07-09 05:52:10 +08:00 这不是很基础的东西吗... |
![]() | 35 okampfer 2022-07-09 10:01:52 +08:00 挺不错的题,也是挺基础的题。正好下周有个面试,就用这道题考考候选人。 还有一个点我觉得可以考一下,就是 setCount 有没有更安全的调用方式,就是 setCount(prevCount => prevCount + 1) 。 不过各位我有个疑问,https://codesandbox.io/s/react-interview-increment-useeffect-g4r99j?file=/src/App.tsx ,我加了一个 useEffect 并依赖于 countRef.current ,我点 increment 了之后居然输出了 countRef.current 的最新值?!不是说更新 ref 不会触发重新渲染吗? 说起来我觉得即使有经验的 React 开发都可能会偶尔懵逼犯这些低级错误,React 在心智负担这点上面确实不如 Vue 、soidjs 有优势。 很高兴有人提到 solidjs ,就是生态还不行得等。 |
36 looking0truth 2022-07-09 10:28:52 +08:00 @okampfer 因为你的 setCount 触发的 rerender 啊 |
![]() | 38 okampfer 2022-07-09 10:40:17 +08:00 |
![]() | 39 gydi 2022-07-09 10:45:33 +08:00 via Android @okampfer 你之前的代码里点击触发 rerender 是因为 setcount 了,不是因为 ref current 的值变了 |
![]() | 41 westoy 2022-07-09 11:57:28 +08:00 |
![]() | 42 AV1 2022-07-09 12:10:17 +08:00 这题目对 react 来说是非常基础的东西,可以说是踏入 react 生态的第一步就要遇到的问题。 |
![]() | 43 okampfer 2022-07-09 15:23:39 +08:00 @gydi @looking0truth #39 是的,我又实验了一下,确实是……一旦注释掉 setCount 那一行,就无法输出最新的 ref.current 值了。 |
44 AyaseEri 2022-07-09 16:45:34 +08:00 会被打死,不如考考 React Fiber |
45 vision1900 2022-07-09 21:18:09 +08:00 @AyaseEri 初中级就考 Fiber ,真卷啊 |
46 vision1900 2022-07-09 21:18:45 +08:00 可以参考这篇文章: https://beta.reactjs.org/learn/state-as-a-snapshot React 的 state 不是普通的 JS 变量 |
![]() | 47 nazalewoyuanyi 2022-07-10 08:38:34 +08:00 via Android @rabbbit 应该只会打印出来一个 0 吧,只执行了一次 |
49 vision1900 2022-07-11 00:12:06 +08:00 可以这么写,虽然有点 hack 的感觉: ``` useEffect(() => { setTimeout(() => { setCount(val => { console.log(val) return val; }) }, 10 * 1000); }, []) ``` |
![]() | 50 prayx 2022-07-26 14:15:04 +08:00 合理,考察对 React Hooks 和闭包的理解。 |
![]() | 51 QKgf555H87Fp0cth 2022-09-06 16:31:02 +08:00 主要考的还是 setTimeout |