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

react-router路由无法工作,三种history.push方法均失效求助

Fixing Route Updates in Your TypeScript Electron App with React-Redux, React-Router & Redux-Observable

Hey there, I totally get the frustration of trying every trick in the book to get route navigation working and coming up empty—especially when you’re combining Electron, React Router, Redux, and Redux Observable, which have their own little quirks when used together. Let’s break down the most likely issues and fixes:

1. First: Check Your Router Container (Critical for Electron!)

Electron loads your app via the file:// protocol, and BrowserRouter (the default for web apps) relies on HTML5 History API which doesn’t play nice with local file paths. This is the #1 gotcha for Electron + React Router setups.

  • Swap it out for either:

    • HashRouter: Adds a # to your paths, which works seamlessly with local file URLs
    • MemoryRouter: Manages routes entirely in memory, perfect for desktop apps that don’t need visible URL paths

    Example with HashRouter:

    import { HashRouter as Router, Routes, Route } from 'react-router-dom';
    import Home from './components/Home';
    import Dashboard from './components/Dashboard';
    
    function App() {
      return (
        <Router>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/dashboard" element={<Dashboard />} />
          </Routes>
        </Router>
      );
    }
    

2. Properly Export & Use a History Instance (For React Router v5 or Earlier)

If you’re on React Router v5, manually creating and exporting a history instance is the right approach—your previous attempts might have missed a key step:

  • Create a src/history.ts file:
    // Use createHashHistory instead of createBrowserHistory for Electron
    import { createHashHistory } from 'history';
    export const history = createHashHistory();
    
  • Wrap your app with the generic Router component (not BrowserRouter) and pass the history instance:
    import { Router, Routes, Route } from 'react-router-dom';
    import { history } from './history';
    
    function App() {
      return (
        <Router history={history}>
          {/* Your routes here */}
        </Router>
      );
    }
    
  • Now you can use this history instance anywhere—components or Redux Observable epics:
    Component example:
    import { history } from '../history';
    
    function LoginButton() {
      const handleLogin = () => {
        // Do auth logic...
        history.push('/dashboard');
      };
    
      return <button onClick={handleLogin}>Login</button>;
    }
    
    Redux Observable epic example:
    import { history } from '../history';
    import { ofType } from 'redux-observable';
    import { map } from 'rxjs/operators';
    
    export const loginSuccessEpic = (action$) =>
      action$.pipe(
        ofType('LOGIN_SUCCESS'),
        map(() => {
          history.push('/dashboard');
          return { type: 'NAVIGATED_TO_DASHBOARD' };
        })
      );
    

3. React Router v6? Use useNavigate & Exportable Router Instance

If you’re on React Router v6, useHistory was replaced with useNavigate, and for non-component code (like epics), you’ll need to create a router instance and export its navigate method:

  • Create src/router.ts:
    import { createHashRouter, RouterProvider } from 'react-router-dom';
    import Home from './components/Home';
    import Dashboard from './components/Dashboard';
    
    export const router = createHashRouter([
      { path: '/', element: <Home /> },
      { path: '/dashboard', element: <Dashboard /> },
    ]);
    
    // Export the navigate method for use outside components
    export const navigate = router.navigate;
    
  • Use RouterProvider in your App:
    import { RouterProvider } from 'react-router-dom';
    import { router } from './router';
    
    function App() {
      return <RouterProvider router={router} />;
    }
    
  • Usage in components and epics:
    Component:
    import { useNavigate } from 'react-router-dom';
    
    function LoginButton() {
      const navigate = useNavigate();
      const handleLogin = () => navigate('/dashboard');
    
      return <button onClick={handleLogin}>Login</button>;
    }
    
    Epic:
    import { navigate } from '../router';
    import { ofType } from 'redux-observable';
    import { map } from 'rxjs/operators';
    
    export const loginSuccessEpic = (action$) =>
      action$.pipe(
        ofType('LOGIN_SUCCESS'),
        map(() => {
          navigate('/dashboard');
          return { type: 'NAVIGATED_TO_DASHBOARD' };
        })
      );
    

4. Quick Sanity Checks

  • Make sure react-router and react-router-dom are the exact same version—mismatches cause weird, hard-to-debug issues.
  • If you’re using TypeScript, install @types/history if you’re manually creating a history instance (for v5).
  • Avoid duplicating route state in Redux—React Router already manages this for you; use Redux only for business logic.

Hopefully one of these fixes gets your routes updating properly!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:13:02