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

React-Router-Dom v6结合Mobx时useNavigate调用报错问题求助

问题原因

你直接在main.tsx的顶层作用域调用useNavigate(),违反了React Hook的核心规则:Hook只能在函数组件的主体内部或自定义Hook中调用,因此触发了"Invalid hook call"错误。

解决方案

方案1:继续使用history对象(适配React Router v6,改动最小)

React Router v6的BrowserRouter默认内部管理history,但你可以通过Router组件手动传入自定义的history实例,延续旧版本的用法:

  1. 确保安装history包:
npm install history
  1. 修改main.tsx:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './app/layout/App'
import './app/layout/styles.css'
import 'semantic-ui-css/semantic.min.css'
import 'react-toastify/dist/ReactToastify.min.css'
import 'react-calendar/dist/Calendar.css'
import 'react-datepicker/dist/react-datepicker.css'
import { store, StoreContext } from './app/stores/store'
// 替换BrowserRouter为Router,引入createBrowserHistory
import { Router } from 'react-router-dom'
import { createBrowserHistory } from 'history'

export const history = createBrowserHistory()

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <StoreContext.Provider value={store}>
      {/* 传入自定义history实例 */}
      <Router location={history.location} navigator={history}>
        <App />
      </Router>
    </StoreContext.Provider>
  </React.StrictMode>
)
  1. 修改userStore.ts(和旧版本用法完全一致):
import { UserFormValues } from './../models/user';
import { makeAutoObservable, runInAction } from "mobx";
import { User } from "../models/user";
import agent from '../api/agent';
import { store } from './store';
import { history } from '../../main';

export default class UserStore {
    user: User | null = null;

    constructor() {
        makeAutoObservable(this);
    }

    logout = () => {
        store.commonStore.setToken(null);
        window.localStorage.removeItem('jwt');
        this.user = null;
        history.push('/');
    }
}

方案2:向Store注入navigate函数(符合v6的Hook设计)

如果不想依赖history包,可以在根组件中获取navigate并注入到Store中:

  1. 修改main.tsx,添加包装组件获取navigate:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './app/layout/App'
import './app/layout/styles.css'
import 'semantic-ui-css/semantic.min.css'
import 'react-toastify/dist/ReactToastify.min.css'
import 'react-calendar/dist/Calendar.css'
import 'react-datepicker/dist/react-datepicker.css'
import { store, StoreContext } from './app/stores/store'
import { BrowserRouter, useNavigate } from 'react-router-dom'

// 包装组件:获取navigate并注入Store
const AppWrapper = () => {
  const navigate = useNavigate();
  
  React.useEffect(() => {
    store.setNavigate(navigate);
  }, [navigate]);

  return <App />;
}

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <StoreContext.Provider value={store}>
      <BrowserRouter>
        <AppWrapper />
      </BrowserRouter>
    </StoreContext.Provider>
  </React.StrictMode>
)
  1. 更新store.ts,添加存储navigate的属性和方法:
import UserStore from './userStore';
import CommonStore from './commonStore';
import { NavigateFunction } from 'react-router-dom';

class RootStore {
  userStore: UserStore;
  commonStore: CommonStore;
  navigate?: NavigateFunction;

  constructor() {
    this.userStore = new UserStore(this);
    this.commonStore = new CommonStore(this);
  }

  setNavigate = (navigate: NavigateFunction) => {
    this.navigate = navigate;
  }
}

export const store = new RootStore();
export const StoreContext = React.createContext(store);
  1. 修改userStore.ts,通过RootStore调用navigate:
import { UserFormValues } from './../models/user';
import { makeAutoObservable, runInAction } from "mobx";
import { User } from "../models/user";
import agent from '../api/agent';
import { RootStore } from './store';

export default class UserStore {
    user: User | null = null;
    private rootStore: RootStore;

    constructor(rootStore: RootStore) {
        makeAutoObservable(this);
        this.rootStore = rootStore;
    }

    logout = () => {
        this.rootStore.commonStore.setToken(null);
        window.localStorage.removeItem('jwt');
        this.user = null;
        this.rootStore.navigate?.('/');
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:39:15