我正在我的项目中使用react router dom v6和mobex,当我使用它时,出现了一个错误,如下所示.

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'
import { BrowserRouter } from 'react-router-dom'
import { useNavigate } from 'react-router-dom';
export const navigate = useNavigate();

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <StoreContext.Provider value={store}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </StoreContext.Provider>
  </React.StrictMode>
)

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 { navigate } 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;
        navigate('/');
    }
}

错误:

"Invalid hook call. Hooks can only be called inside the body of a function component"

在旧版本中,当我这样做时,它正在工作:

main.tsx:

...
...
import { createBrowserHistory } from "history";
export const history = createBrowserHistory();
...
...

and userstore.tsx:

import { makeAutoObservable, runInAction } from "mobx";
import agent from "../api/agent";
import { User, UserFormValues } from "../models/user";
import { store } from "./store";
import { history } from "../../index";

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("/");
  };

我如何解决这个问题?

推荐答案

该行const navigate = useNavigate()只能位于React组件或自定义挂钩内,因为useNavigate是挂钩.参见Rules of Hooks了解更多信息.解决这个问题的一种方法是更改logout函数,使其以navigate为参数,如下所示:

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

在组件中调用useNavigate,其中调用logout,并将navigate作为参数.例如:

import UserStore from "./UserStore"; // use the correct path
import { useNavigate } from "react-router-dom";

export default function Component() {
  const navigate = useNavigate();
  const userStore = UserStore();
  userStore.logout(navigate);

  return <div></div>;
}

Javascript相关问答推荐

模块与独立组件

如何从JSON数组添加Google Maps标记—或者如何为数组添加参数到标记构造器

togglePopover()不打开但不关闭原生HTML popover'

为什么promise对js中的错误有一个奇怪的优先级?

jQuery s data()[storage object]在vanilla JavaScript中?'

Chromium会将URL与JS一起传递到V8吗?

引用在HTMLAttributes<;HTMLDivElement>;中不可用

XSLT处理器未运行

如何使用子字符串在数组中搜索重复项

以Angular 实现ng-Circle-Progress时出错:模块没有导出的成员

扩展类型的联合被解析为基类型

MarkLogic-earch.suggest不返回任何值

如何在我的Next.js项目中.blob()我的图像文件?

如何确保预订系统跨不同时区的日期时间处理一致?

如何在Jest中模拟函数

如何使用[ModelJSON,ArrayBuffer]调用tf.loadGraphModelSync

如何使用Reaction路由导航测试挂钩?

使用Perl Selify::Remote::Driver执行Java脚本时出错

将字体样式应用于material -UI条形图图例

将Windows XP转换为原始数据以在html前端中显示