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

使用React Testing Library测试时ref.current未赋值的原因

React测试中useRef.current始终为null的原因及解决办法

将以下测试代码中,r.current始终为null,无法被设置为HtmlDivElement,请问原因是什么?我使用的是Jest 27版本的React Testing Library,尝试升级到该库的最新版本后,问题仍未解决。

测试代码:

test('test-1', async () => {
  const Comp = () => {
    const r = React.useRef(null);
    React.useEffect(() => {
      if (r.current) {
        console.log(r.current);
      }
    });
    return <div ref={r}> Hello </div>;
  };
  render(<Comp />);
});

核心原因

问题出在测试执行时机与React副作用的异步特性不匹配:

  • React的useEffect回调是异步执行的,会在组件挂载完成后加入任务队列,不会同步阻塞代码执行。
  • 你的测试代码调用render后就直接结束了,此时Jest的测试进程已经终止,useEffect的回调还没来得及执行,自然看不到r.current被赋值后的输出。

解决办法

1. 用waitFor等待副作用执行完成

React Testing Library的waitFor可以等待异步操作完成,确保useEffect的回调执行后再结束测试:

import { render, waitFor } from '@testing-library/react';
import React from 'react';

test('test-1', async () => {
  let refCurrent = null;
  const Comp = () => {
    const r = React.useRef(null);
    React.useEffect(() => {
      refCurrent = r.current;
      if (refCurrent) {
        console.log(refCurrent);
      }
    });
    return <div ref={r}> Hello </div>;
  };
  
  render(<Comp />);
  // 等待useEffect执行,确保ref被赋值
  await waitFor(() => {
    expect(refCurrent).not.toBeNull();
  });
});

2. 遵循RTL测试最佳实践:直接查询DOM元素

如果你的测试目的是验证元素是否渲染,完全不需要依赖useRef,用RTL的查询方法更直接,也符合“测试用户可见行为”的原则:

import { render, screen } from '@testing-library/react';

test('test-1', () => {
  render(<div> Hello </div>);
  // 直接查询元素并断言
  expect(screen.getByText(' Hello ')).toBeInTheDocument();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:50:34