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

使用Vite从React16迁移至React18时遇路由中间件函数错误

React 16迁移React 18(Vite):路由与中间件报错解决

我正在用Vite将React 16应用迁移至React 18,目前遇到路由与中间件相关问题,入口文件代码如下:

import React from 'react';
import { createRoot } from "react-dom/client";
import { Provider } from 'react-redux';
import { createBrowserHistory } from 'history';
import { createStore, applyMiddleware, compose } from 'redux';
import { BrowserRouter as Router, Route, cr  } from "react-router-dom";
import createSagaMiddleware from 'redux-saga';

import globalStore from './reducers';
import sagas from './sagas';
import './i18n';
import './globalStyles.css';

import App from './App';
import * as serviceWorker from './serviceWorker';

const history = createBrowserHistory();
const sagaMiddleware = createSagaMiddleware();
const enhancers = [applyMiddleware(routerMiddleware(history), sagaMiddleware)];

const composeEnhancers =
    process.env.NODE_ENV !== 'production' &&
    typeof window === 'object' &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
        ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
                shouldHotReload: false,
                trace: true,
                traceLimit: 25,
          })
        : compose;

const store = createStore(globalStore(history), composeEnhancers(...enhancers));

sagaMiddleware.run(sagas);
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
    <Provider store={store}>
        <Router history={history}>
            <App history={history} />
        </Router>
    </Provider>
);

serviceWorker.unregister();

运行时出现错误:

TypeError: middleware is not a function


问题原因及解决步骤

  1. 未导入且无需使用routerMiddleware
    代码中调用的routerMiddleware(history)既没有导入,而且React Router v6已经移除了对自定义history的直接支持,也不再需要这个中间件。这是导致"middleware is not a function"报错的核心原因——undefined被当成中间件传入applyMiddleware。

  2. 修正React Router导入错误
    代码里import { BrowserRouter as Router, Route, cr } from "react-router-dom";中的cr是拼写错误,直接删除即可。

  3. 移除手动创建的history
    React Router v6的BrowserRouter已经内置了history管理,不再接受history prop,所以删掉createBrowserHistory()的创建代码,以及Router组件的history传入。

  4. 组件内访问路由的方式调整
    之前通过props传入history的方式可以换成React Router v6的useNavigate钩子,在App组件内直接调用即可。

修改后的完整代码

import React from 'react';
import { createRoot } from "react-dom/client";
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import { BrowserRouter as Router } from "react-router-dom";
import createSagaMiddleware from 'redux-saga';

import globalStore from './reducers';
import sagas from './sagas';
import './i18n';
import './globalStyles.css';

import App from './App';
import * as serviceWorker from './serviceWorker';

const sagaMiddleware = createSagaMiddleware();
// 移除了routerMiddleware,只保留saga中间件
const enhancers = [applyMiddleware(sagaMiddleware)];

const composeEnhancers =
    process.env.NODE_ENV !== 'production' &&
    typeof window === 'object' &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
        ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
                shouldHotReload: false,
                trace: true,
                traceLimit: 25,
          })
        : compose;

// 如果你的globalStore不再依赖history参数,这里去掉history传入
const store = createStore(globalStore(), composeEnhancers(...enhancers));

sagaMiddleware.run(sagas);
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
    <Provider store={store}>
        <Router>
            <App />
        </Router>
    </Provider>
);

serviceWorker.unregister();

补充说明

如果你的reducer之前依赖history对象,需要调整reducer的逻辑。另外,React 18搭配Vite时,serviceWorker的配置可能需要改用Vite的PWA插件,不过暂时可以保留现有代码,后续再按需优化。

内容的提问来源于stack exchange,提问作者niko hustić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:35:34