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

Jest模拟useNavigate未更新路径,取消模拟后遇Request未定义错误

问题分析与解决方案

1. 多步骤表单跳转后状态与路由不同步问题

你遇到的核心问题是:提交后currentStep状态已更新(标题显示Step2),但表单元素仍停留在step1,且路由路径未更新。结合代码来看,问题出在以下几点:

问题根源

  • 路由路径格式错误:navigate(step${currentStep + 1})生成的是相对路径,会在当前路径/signup/step1基础上拼接成/signup/step1/step2,和预期的/signup/step2不匹配。
  • 测试未验证路由跳转:现有测试只检查了标题更新,未确认路由路径是否正确,也没等待路由跳转完成后再校验表单元素。
  • 组件渲染逻辑不匹配:手动修改路径能显示正确表单,说明Form组件是基于路由参数渲染步骤,但提交时仅更新了currentStep状态,未同步路由与状态的关联。

修复步骤

调整提交函数的路由跳转逻辑

改用绝对路径确保跳转到正确路由:

const onSubmit = () => {
  nextStep();
  // 使用绝对路径替代相对路径,避免嵌套路由错误
  navigate(`/signup/step${currentStep + 1}`);
};

完善测试逻辑,等待路由更新

测试中需同时验证路由路径和对应步骤的表单元素:

import { MemoryRouter, Routes, Route } from 'react-router-dom';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('Move to the next step after form field is valid & submitted', async () => {
  const user = userEvent.setup();
  render(
    <MemoryRouter initialEntries={['/signup/step1']}>
      <Routes>
        <Route path="/signup/*" element={<Form />} />
      </Routes>
    </MemoryRouter>,
  );

  await fillUserInfo(user); // 确保使用userEvent处理用户操作
  await clickSubmit(user);

  await waitFor(() => {
    // 验证路由路径是否正确
    expect(window.location.pathname).toBe('/signup/step2');
    // 验证Step2专属表单元素存在(替换为你实际的元素标识)
    expect(screen.getByLabelText('Step2 手机号')).toBeInTheDocument();
    expect(screen.getByText('Step2')).toBeInTheDocument();
  });
});

同步路由与组件状态

在Form组件中添加路由监听,确保路由变化时同步更新currentStep:

import { useLocation } from 'react-router-dom';

const Form = () => {
  const location = useLocation();
  const [currentStep, setCurrentStep] = useState(1);

  // 组件挂载或路由变化时,根据路径更新currentStep
  useEffect(() => {
    const stepMatch = location.pathname.match(/step(\d+)/);
    if (stepMatch) {
      setCurrentStep(Number(stepMatch[1]));
    }
  }, [location]);

  // 其余逻辑...
};

2. 取消模拟useNavigate后出现ReferenceError: Request is not defined

Node.js 18+环境下出现该错误,是因为Jest默认的jsdom环境未提供全局Request对象,而React Router v6+依赖该对象。

修复方案

添加Request polyfill

  1. 安装依赖:
npm install --save-dev @remix-run/web-fetch
  1. 在Jest配置文件(jest.config.js)中指定初始化文件:
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/src/setupTests.js'],
  // 其他配置...
};
  1. 在src/setupTests.js中添加polyfill:
import { Request, Response, Headers } from '@remix-run/web-fetch';

if (!globalThis.Request) {
  globalThis.Request = Request;
  globalThis.Response = Response;
  globalThis.Headers = Headers;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:16:21