React中useRef存储前值的行为疑惑:为何打印结果不一致?
问题解析:useEffect中count与prevCountRef.current值相同,但页面显示count大1的原因及执行顺序
核心原因
这种差异是由React组件的渲染周期和useEffect的执行时机不同导致的:组件渲染生成JSX时,prevCountRef.current还未被更新;而useEffect是在DOM更新完成后才执行,此时会将当前count赋值给ref,所以控制台输出两者相等。
详细执行流程
初始渲染
- 初始化状态:
count = 0,prevCountRef.current = undefined(useRef默认初始值为undefined) - 渲染JSX:页面显示
Current Count: 0,Previous Count: undefined - 执行依赖
count的useEffect:将prevCountRef.current设为0,控制台输出0 0
第一次点击Increment按钮后
- 触发
handleIncrement:调用setCount(0 + 1),React标记state需要更新 - 组件重新渲染:
- 新的
count值为1(state更新后的最新值) prevCountRef.current仍然保留上一次的0(useRef的值在组件重新渲染之间持久化,未被修改)- 渲染JSX:页面显示
Current Count: 1,Previous Count: 0(此时count比prev大1)
- 新的
- 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
相关产品推荐
相关产品推荐

