广东马上信息科技
做教育服务的,从小初高到大专大学,都有客户,卖教学硬件和捆绑的软件,同时还提供很多 Sass 软件
此次面试有三个问题没回答好,复盘一下
第三题别被标题迷惑了,邪门的很!
React 中在 setTimeout 内调用 setState
这是个非常常见的问题,一般会问为什么拿到的是旧值
这个面试官直接难度提上来一档,如果没研究过 React 原理,可能会吃哑巴亏
当时是这样的:
面试官:嗯看来你对 React 的理解是没有 Vue 那么深入
我:没看过 React 源码
面试官:我们没想过招多牛的人,没看过没关系
当然研究过也可能翻车,看完下面问题和复盘实操就懂了
调用三次 setState,该组件会重新渲染几次?在 setTimeout 内调用三次呢?
首先是正常的调用三次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import React, { FC, useState } from 'react';
const TestPage: FC = () => {
let [count, setCount] = useState(0);
function add() {
setCount(count + 1);
console.log(1, count);
setCount(count + 1);
console.log(2, count);
setCount(count + 1);
console.log(3, count);
}
console.log('render', count);
return <button onClick={add}>{count}</button>;
};
export default TestPage;打开页面控制台会立即打印
1
render 0
点击按钮后
1
2
3
41 0
2 0
3 0
render 1这里很简单,react 会合成多次 setState,所以这边只会渲染一次
并且因为闭包的原因,
add
函数拿到的是更新前TestPage
函数内的count
,所以count
一直是0
最后合并更新时会拿最后一次的结果,因为
count
一直为0
,所以结果是0 + 1
然后是
setTimeout
内1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import React, { FC, useState } from 'react';
const TestPage: FC = () => {
let [count, setCount] = useState(0);
setTimeout(() => {
function add() {
setCount(count + 1);
console.log(1, count);
setCount(count + 1);
console.log(2, count);
setCount(count + 1);
console.log(3, count);
}
}, 1000);
console.log('render', count);
return <button onClick={add}>{count}</button>;
};
export default TestPage;这里就很迷了,我知道在
setTimeout
内更新状态会脱离react
的事件流导致立刻渲染,所以猜测会渲染三次但是实际试了下,控制台是这样输出的:
1
2
3
4
5
6render 0
render 1
1 0
render 1
2 0
3 0回调内次数一直为
0
,很好理解,因为闭包的原因拿到的一直是一开始的count
但是啊,除去第一次渲染,
setState
调用三次却只触发了两次渲染,经过测试最后一次必定不会触发渲染这里就非常非常的奇怪了,到底是为啥啊…
TODO: 我到现在也是没搞明白,现在去啃
react
源码肯定不现实,维护了N
年的庞然大物不是三下两下就能吃完的,以后再说吧
Vue3 副作用中使用 setTimeout,里面的响应式对象会被追踪吗?
当时我光速回答不会(看过源码老自信了)
然后:
面试官:副作用是什么意思
我:函数依赖了外部的变量,导致其执行结果的不确定性,这就是副作用
面试官:看来你对函数式编程不太理解啊
我心里:我简历里也没写熟悉函数式思维啊??(虽然我稍微钻研过)
面试官:副作用就是纯函数相反的概念
我心里:那我刚刚说的没错啊???
我:那…
面试官:下一个问题
还不等我反驳,直接开始下一个问题…挺无语的
而且听他的语气我这题回答错了(实际回答正确),当时挺心虚的,被狠狠的拿捏了(PUA)
直接来看代码:
1 | import { reactive, effect } from 'vue'; |
控制台:
1 | 1 |
只执行了一次,并没有触发副作用
有人会问为什么是 1
啊
啊这,很简单的事件循环问题…我甚至懒得回答,拜托你去看看我的这一篇文章:事件循环
左栏固定,右侧自适应撑满宽度的布局?
这个问题很简单,我就随口说了三种:
flex
布局float: left
+BFC
实现inline-block
左栏固定宽度,右侧calc(100% - width)
计算
那使用 flex
布局时,有哪些方法固定左侧宽度?
到这里还一切正常:
使用
flex-basic
固定左侧宽度使用
width
也行
分别使用这两种方式固定左侧宽度,缩放浏览器窗口时会有什么不同的表现?
???????
这个问题真的是给我问到了,也太刁钻了
我:不知道
面试官:好吧,下一题
然后经过了狠狠的复盘发现:
TODO: ….好像完全没有区别???我人傻掉