You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React状态对象数值修改无效?求解likes: data.likes +1的问题

React点赞按钮状态更新异常:likes数值不变化的问题解决

问题根源

你这段代码的核心问题有两个:

  1. 连续两次调用setData导致更新被覆盖:第一次修改likes后,第二次调用setData仅修改isLiked,且基于当前渲染周期的旧data对象展开,直接覆盖了第一次的likes变更。
  2. 状态更新未使用函数式依赖:当新状态依赖旧状态值时,直接使用当前data会因为React状态更新的异步性,拿到的并非最新状态。

修正后的代码

const initialState = {
   likes: 100,
   dislikes: 25,
   isLiked: false,
   isDisliked: false
}

const [data, setData] = useState(initialState)

const handleLikes = e => {
    // 使用函数式更新,确保获取最新的prevState
    setData(prevState => {
        if (prevState.isLiked) {
            return { 
                ...prevState, 
                likes: prevState.likes - 1, 
                isLiked: false 
            };
        } else {
            return { 
                ...prevState, 
                likes: prevState.likes + 1, 
                isLiked: true 
            };
        }
    })
}

<button className={`like-button ${data.isLiked ? 'liked' : ''}`} onClick={handleLikes}>Like | <span className='likes-counter'>{data.likes}</span></button>

原理说明

React的状态更新是异步批量执行的,在同一个渲染周期内,组件内的状态变量(比如data)会保持当前渲染的旧值,不会因为调用setData就立即更新。

举个简单例子:

// 错误示例:两次更新后number最终为1
let number = 0;
setNumber(number + 1);
setNumber(number + 1);

两次调用setNumber时,number的值都是初始的0,所以最终只会生效最后一次更新,结果为1。

而使用函数式更新时,React会每次传入最新的状态值:

// 正确示例:两次更新后number最终为2
setNumber(prevNumber => prevNumber + 1);
setNumber(prevNumber => prevNumber + 1);

每次更新都基于上一次的最新状态,所以最终结果符合预期。

总结

  • 同一个函数中修改状态时,尽量合并成一次setState调用,避免多次调用导致的覆盖问题
  • 当新状态依赖旧状态值时,必须使用函数式更新(接收prevState参数),确保获取到最新的状态数据

内容的提问来源于stack exchange,提问作者5ecured

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:24:54