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

React v19下如何实现不渲染时访问ref.current的usePrevious Hook?

React v19 下 usePrevious Hook 的正确实现方式

我之前用以下代码实现usePrevious Hook:

import { useEffect, useRef } from 'react';

export const usePrevious = (value: unknown) => {
  const ref = useRef<unknown>();

  useEffect(() => {
    ref.current = value;
  });

  return ref.current;
};

升级至React v19后,触发ESLint报错:

Ref values (the current property) may not be accessed during render. (eslint(react-compiler/react-compiler))

报错原因

React v19的编译器严格禁止在渲染阶段访问ref的current属性。ref是可变容器,直接在渲染阶段读取会导致渲染结果依赖可变状态,破坏渲染的可预测性与纯函数特性。原实现中return ref.current属于在渲染阶段读取可变ref值,因此触发报错。

正确实现方式

以下两种实现均符合React v19编译器要求:

方式一:使用单个ref保存当前与历史值

import { useRef } from 'react';

export function usePrevious<T>(value: T): T | undefined {
  const ref = useRef<{ current: T | undefined; previous: T | undefined }>({
    current: undefined,
    previous: undefined,
  });

  if (ref.current.current !== value) {
    ref.current.previous = ref.current.current;
    ref.current.current = value;
  }

  return ref.current.previous;
}

方式二:使用两个独立ref

import { useRef } from 'react';

export function usePrevious<T>(value: T): T | undefined {
  const previousRef = useRef<T>();
  const currentRef = useRef<T>();

  if (currentRef.current !== value) {
    previousRef.current = currentRef.current;
    currentRef.current = value;
  }

  return previousRef.current;
}

实现说明

两种实现均在渲染阶段完成值的更新逻辑,避免了在渲染阶段读取可变ref的current属性作为返回值,同时保证返回的是上一次传入的value值,完全适配React v19的编译器规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 21:34:53