在上一期《「React实战面试题」:状态更新的并发问题与解决方案》关于快速点击计数问题的讨论中,相信很多同学都找到了正确答案:
根本原因:多个状态更新基于了相同的旧状态值(选项B)
最佳解决方案:使用函数式更新 setLikes(prevLikes => prevLikes + 1)(选项A)
这正好为我们今天的问题做了很好的铺垫!
今天我们来看一个相对轻松但很经典的问题。这是在面试中经常被问到的React基础题,但往往能暴露候选人对React状态更新机制的理解深度。
假设你正在开发一个简单的计数器组件,由于某种业务需求(比如积分规则),你需要在每次点击时让计数器增加3:
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
return (
<button onClick={handleClick}>
点击增加3 (当前: {count})
</button>
);
}
请仔细观察上面的代码,然后回答:
当用户点击按钮1次后,count的值会是多少?
在心中默默给出你的答案,然后继续往下看。
A. 3 - 符合预期,三次 +1 操作 B. 2 - 只有部分更新生效 C. 1 - 只有一次更新生效 D. 0 - 没有任何变化
在选择答案之前,考虑以下几个关键点:
当你在一个函数中多次调用setState时,这些更新是立即执行还是批量处理?
在handleClick函数执行期间,count变量的值是固定的还是会动态变化?
React为了性能优化,对状态更新采用了什么策略?
如果你已经有了答案,不妨再思考几个相关问题:
虽然这个例子看起来很简单,但类似的问题在实际开发中经常出现:
const handleSubmit = () => {
setErrors({}); // 清空错误
setLoading(true); // 显示加载
setSubmitted(true); // 标记已提交
// 这三个状态更新会如何执行?
};
const addToCart = () => {
setCartItems([...cartItems, newItem]);
setCartCount(cartCount + 1);
setCartTotal(cartTotal + newItem.price);
// 购物车状态的同步更新
};
const handleCombo = () => {
setScore(score + 100); // 基础分数
setScore(score + 50); // 连击奖励
setScore(score + 25); // 时间奖励
// 实际得分是多少?
};
请在评论区分享:
想要验证你的答案?可以在本地创建这个组件试试:
import React, { useState } from'react';
function TestCounter() {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log('点击时count值:', count);
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
console.log('设置后count值:', count); // 这里会输出什么?
};
console.log('渲染时count值:', count);
return (
<div>
<button onClick={handleClick}>点击测试</button>
<p>当前计数: {count}</p>
</div>
);
}
观察控制台的输出,你会发现一些有趣的现象!
这个问题涉及React的几个核心概念:
不管你的答案是什么,重要的是理解背后的原理。React的状态管理机制是整个生态系统的基础,深入理解它对提升React技能非常重要。
🎯 记得在评论区留下你的答案和理由,让我们一起讨论和学习!