I'am using react-router-dom v6 and mobex in my project and get an error when I use it as below.
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('/');
}
}
Error:
"Invalid hook call. Hooks can only be called inside the body of a function component"
In the old version it was working when I did it like this below:
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("/");
};
How can i solve this problem?
CodePudding user response:
You cannot use hooks in class component. for route trough class component there is another way to do that. but I think in router 6 class component support is dropped. so you can change your class component to function component it is easy way.
CodePudding user response:
This line const navigate = useNavigate()
can only be inside a React component or custom hook, as useNavigate
is a hook. Seee Rules of Hooks to know more. One way to solve this is to change your logout
function so it takes navigate
as parameter, like so:
logout = (navigate) => {
store.commonStore.setToken(null);
window.localStorage.removeItem("jwt");
this.user = null;
navigate("/");
};
And call useNavigate
in the component where you call logout
and give navigate
to it as paramater. Like so as an example:
import UserStore from "path/";
import { useNavigate } from "react-router-dom";
export default function Component() {
const navigate = useNavigate();
const userStore = UserStore();
userStore.logout(navigate);
return <div></div>;
}