admin 管理员组文章数量: 1086019
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 = () => {
storemonStore.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 ponent"
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 = () => {
storemonStore.setToken(null);
window.localStorage.removeItem("jwt");
this.user = null;
history.push("/");
};
How can i solve this problem?
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.monStore.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 ponent"
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.monStore.setToken(null);
window.localStorage.removeItem("jwt");
this.user = null;
history.push("/");
};
How can i solve this problem?
Share Improve this question edited Jul 30, 2022 at 10:55 Youssouf Oumar 46.6k16 gold badges103 silver badges105 bronze badges asked Jul 30, 2022 at 10:21 erhanbasturkerhanbasturk 611 silver badge5 bronze badges3 Answers
Reset to default 3This line const navigate = useNavigate()
can only be inside a React ponent or custom hook, as useNavigate
is a hook. See Rules of Hooks to know more. One way to solve this is to change your logout
function, so it takes navigate
as a parameter, like so:
logout = (navigate) => {
store.monStore.setToken(null);
window.localStorage.removeItem("jwt");
this.user = null;
navigate("/");
};
And call useNavigate
in the ponent where you call logout
and give navigate
to it as a parameter. Like so as an example:
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>;
}
Issue
React hooks can only be used within a React function ponent and the useNavigate
hook can only be used within a routing context.
Solution
Access the navigate
function via the useNavigate
hook from a React function ponent and pass a reference to navigate
to the logout
handler.
logout = ({ navigate }) => {
store.monStore.setToken(null);
window.localStorage.removeItem("jwt");
this.user = null;
navigate("/");
};
...
const SomeComponent = () => {
const navigate = useNavigate();
...
UserStore.logout({ navigate });
...
};
Alternative Solution
Import and use the HistoryRouter
and continue using the custom history
object as previously. This requires history@5
package dependency, install it if necessary (run npm i -S history@5
).
Example:
Create and export history
object.
import { createBrowserHistory } from "history";
export const history = createBrowserHistory();
...
...
import { unstable_HistoryRouter as HistoryRouter } from 'react-router-dom';
import { history } from '../path/to/history';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<StoreContext.Provider value={store}>
<HistoryRouter history={history}>
<App />
</HistoryRouter>
</StoreContext.Provider>
</React.StrictMode>
);
UserStore continues to import the history
object and use it.
import { makeAutoObservable, runInAction } from "mobx";
import agent from "../api/agent";
import { User, UserFormValues } from "../models/user";
import { store } from "./store";
import { history } from "../path/to/history";
export default class UserStore {
user: User | null = null;
constructor() {
makeAutoObservable(this);
}
logout = () => {
store.monStore.setToken(null);
window.localStorage.removeItem("jwt");
this.user = null;
history.push("/");
};
...
You cannot use hooks in class ponent. for route trough class ponent there is another way to do that. but I think in router 6 class ponent support is dropped. so you can change your class ponent to function ponent it is easy way.
本文标签: javascriptreactrouterdom v6 history push and useNavigate problemStack Overflow
版权声明:本文标题:javascript - react-router-dom v6 history push and useNavigate problem - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744092173a2532240.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论