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

React Router v5升级至v6遇TypeScript错误,求解决方案

解决React Router v5升级到v6的TypeScript错误问题

问题分析

React Router v6彻底移除了Route组件的render属性,改用element属性,但element接收的是React元素而非渲染函数,无法像v5那样通过props获取history和location。同时v6中history的概念也发生变化,useNavigate返回的是导航函数而非v5的history对象,直接沿用旧写法会触发TypeScript类型错误。

解决方案

重构withRouter函数,利用v6的路由钩子直接获取导航能力和路由状态,而非通过Route传递props:

import React from "react";
import { Reducer } from "@reduxjs/toolkit";
import { Provider } from "react-redux";
import { MemoryRouter, Route, useNavigate, useLocation, To } from "react-router-dom";
import buildStore from "../redux/store";

export function withRedux(
  ui: React.ReactElement,
  reducer: {
    [key: string]: Reducer;
  },
  initialState: any
) {
  const store = buildStore(initialState, true);
  const dispatchSpy = jest.spyOn(store, "dispatch");

  return {
    result: <Provider store={store}>{ui}</Provider>,
    store,
    dispatchSpy
  };
}

export function withRouter(ui: React.ReactElement) {
  // 明确类型,避免any
  const routerValues = {
    // 兼容v5的history格式,或直接使用navigate函数
    history: undefined as {
      push: (to: To) => void;
      replace: (to: To) => void;
      goBack: () => void;
      goForward: () => void;
      location: ReturnType<typeof useLocation>;
    } | undefined,
    location: undefined as ReturnType<typeof useLocation> | undefined
  };

  // 内部组件用于捕获路由状态
  const CaptureRouteData = () => {
    const navigate = useNavigate();
    const location = useLocation();

    React.useEffect(() => {
      // 包装navigate为v5风格的history对象(按需选择)
      routerValues.history = {
        push: (to) => navigate(to),
        replace: (to) => navigate(to, { replace: true }),
        goBack: () => navigate(-1),
        goForward: () => navigate(1),
        location
      };
      routerValues.location = location;
    }, [navigate, location]);

    return null;
  };

  const result = (
    <MemoryRouter>
      {ui}
      <Route path="*" element={<CaptureRouteData />} />
    </MemoryRouter>
  );

  return { result, routerValues };
}

关键修改点

  1. 替换Route的使用方式:
    v6的Route组件element属性必须传入React元素,因此创建专门的CaptureRouteData组件来承载路由钩子逻辑。

  2. 使用v6路由钩子:

    • useNavigate:获取导航函数,替代v5的history.push/replace等方法
    • useLocation:直接获取当前路由的location对象
  3. 类型安全优化:
    移除any类型,通过ReturnType<typeof useNavigate>和ReturnType<typeof useLocation>推导正确类型,同时按需包装出兼容v5的history对象格式。

  4. 状态同步:
    用useEffect监听navigate和location的变化,确保routerValues始终保持最新的路由状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:40:39