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

React中useRef存储前值的行为疑惑:为何打印结果不一致?

问题解析:useEffect中count与prevCountRef.current值相同,但页面显示count大1的原因及执行顺序

核心原因

这种差异是由React组件的渲染周期和useEffect的执行时机不同导致的:组件渲染生成JSX时,prevCountRef.current还未被更新;而useEffect是在DOM更新完成后才执行,此时会将当前count赋值给ref,所以控制台输出两者相等。

详细执行流程

初始渲染

  1. 初始化状态:count = 0,prevCountRef.current = undefined(useRef默认初始值为undefined)
  2. 渲染JSX:页面显示Current Count: 0,Previous Count: undefined
  3. 执行依赖count的useEffect:将prevCountRef.current设为0,控制台输出0 0

第一次点击Increment按钮后

  1. 触发handleIncrement:调用setCount(0 + 1),React标记state需要更新
  2. 组件重新渲染:
    • 新的count值为1(state更新后的最新值)
    • prevCountRef.current仍然保留上一次的0(useRef的值在组件重新渲染之间持久化,未被修改)
    • 渲染JSX:页面显示Current Count: 1,Previous Count: 0(此时count比prev大1)
  3. DOM更新完成后,执行依赖count的useEffect:
    • 将prevCountRef.current设为当前的count(即1)
    • 控制台输出1 1(此时两者值相等)

修正代码(正确存储前一次状态)

如果想让prevCountRef真正存储上一次的count值,可调整useEffect内的逻辑,先保存旧值再更新ref:

import React, { useState, useEffect, useRef } from 'react';

const PrevCountExample = () => {
  const [count, setCount] = useState(0);
  const prevCountRef = useRef();

  useEffect(() => {
    // 先保存上一次的ref值,再更新为当前count
    const prevCount = prevCountRef.current;
    prevCountRef.current = count;
    console.log('当前count:', count, '上一次count:', prevCount);
  }, [count]);

  const handleIncrement = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Current Count: {count}</p>
      <p>Previous Count: {prevCountRef.current}</p>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
}

export default PrevCountExample

此时控制台会输出当前count和上一次的count值,页面上的Previous Count也会始终显示上一次的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:20:18