using history with react-router-dom v6

I use react-router-dom version 6 and when I use this.props.history.push('/UserDashboard') it does not work. I changed it to

const history = createBrowserHistory();
history.push('/UserDashboard')

but I still have a problem that when i would like to redirect to /UserDashboard just the link change and the page still the first one??

any help??**

        handleSubmit(event){
       

    

event.preventDefault();
const history = createBrowserHistory();
axios({
method: "POST",
url:"http://localhost:3001/users/login",
data:  this.state
}).then((response)=>{
console.log(response.data.user.admin)
if (response.data.success === true && response.data.user.admin === false){
           

const history = createBrowserHistory();
history.push({
pathname:"/users",
state:{
Key : response.data.user }
});
    

        

           

}else if(response.statusCode === 401 ){
alert("Invalid username or password");
window.location.reload(false);
}
})
}

my routes.js file:

    import React from 'react';
import { Navigate } from 'react-router-dom';
import DashboardLayout from './Pages/DashboardLayout';
import AccountView from './Pages/views/account/AccountView';
import CustomerListView from './Pages/views/customer/CustomerListView';
import DashboardView from './Pages/views/reports/DashboardView';
import ProductListView from './Pages/views/product/ProductListView';
import SettingsView from './Pages/views/settings/SettingsView';
import Home from './Pages/home';
import About from './Pages/About';
import Partners from './Pages/Partners';
import Services from './Pages/services';
import Login from './Pages/Login';
import RD from './Pages/RD';
import ContactUs from './Pages/contactus';
import Apply from './Pages/apply';
import PartnerShip from './Pages/partnership';
import News from './Pages/News';
const routes = [
{
path: 'users',
element: <DashboardLayout />,
children: [
{ path: 'account', element: <AccountView /> },
{ path: 'customers', element: <CustomerListView /> },
{ path: 'dashboard', element: <DashboardView /> },
{ path: 'products', element: <ProductListView /> },
{ path: 'settings', element: <SettingsView /> }
]
},
{
path: '/',
element: <Home />,
},
{
path: 'about',
element: <About />
},
{path: 'partners',
element: <Partners />,
    

},
{
path: 'services',
element: <Services />,
    

},
{
path: 'contactus',
element: <ContactUs />,
    

},
{
path: 'login',
element: <Login />,
    

},{
path: 'RD',
element: <RD />,
    

},
{
path: 'apply',
element: <Apply />,
    

},
{
path: 'partnership',
element: <PartnerShip />,
    

},
{
path: 'News',
element: <News />,
    

}
];


export default routes;
214522 次浏览

在 response-router-dom v6中,需要使用 使用导航而不是使用 History。

参见 https://reacttraining.com/blog/react-router-v6-pre/的例子

import React from 'react';
import { useNavigate } from 'react-router-dom';


function App() {
let navigate = useNavigate();
let [error, setError] = React.useState(null);


async function handleSubmit(event) {
event.preventDefault();
let result = await submitForm(event.target);
if (result.error) {
setError(result.error);
} else {
navigate('success');
}
}


return (
<form onSubmit={handleSubmit}>
// ...
</form>
);
}

基于 response-router-dom 源代码,您可以执行以下操作:

import { Router } from 'react-router-dom';


const CustomRouter = ({
basename,
children,
history,
}) => {
const [state, setState] = React.useState({
action: history.action,
location: history.location,
});


React.useLayoutEffect(() => history.listen(setState), [history]);


return (
<Router
basename={basename}
children={children}
location={state.location}
navigationType={state.action}
navigator={history}
/>
);
};

然后让你的历史来自外部:

import { createBrowserHistory } from 'history';


const history = createBrowserHistory();


<CustomRouter history={history}>
...
</CustomRouter>

We all know there is no longer { useHistory } kind of thing in react-router-dom v6. There is better a way to do a work of useHistory.

导航..。

import { useNavigate } from 'react-router-dom';

then just do this after importing

function Test() {
const history = useNavigate();


function handleSubmit(e) {
e.preventDefault();


history('/home');
}


return (
<form onSubmit={handleSubmit}>
<button>Subimt</button>
</form>
)
}

如果仍然在 response v6 + 中使用类组件,另一种解决方案是将新导航对象注入为历史记录。这解决了不能在类组件中使用 navigate()的麻烦问题,尽管您将来应该尝试远离类组件。我发现自己陷入了这种困境,因为我确信其他人仍然拥有大量的代码库。

import React, { Component } from "react";
import { useNavigate } from "react-router-dom";


class MyClass extends Component {
handleClick(e) => {
this.props.history('place-to-route');
}
}
export default (props) => (
<MyClass history={useNavigate()} />
);

中描述的解决方案

Https://reactnavigation.org/docs/use-navigation/

class MyBackButton extends React.Component {
render() {
// Get it from props
const { navigation } = this.props;
}
}


// Wrap and export
export default function(props) {
const navigation = useNavigation();


return <MyBackButton {...props} navigation={navigation} />;
}

Reactjsv6附带了 useNavigate 而不是 useHistory。

= > 首先,您必须像这样导入它: import {useNavigate} from 'react-router-dom'.

= > 然后你只能在这样一个反应函数组件下使用它:

Const navigate = useNavigate () ;

然后你想导航哪条路线,只要把路线名称写成这样:

navigate("/about");

例如: 如果要在单击按钮后导航到 about 页面,则应将

在这个 onClick 事件下导航(“/about”) :

< 按钮 onClick = {() = > 导航(“/about”)} > 转到 about page

谢谢。

基于@Poyoman 的回答:

创建 CustomBrowserRouter 组件:

import React from "react";
import { BrowserHistory, Action, Location } from "history";
import { Router } from "react-router-dom"


interface CustomRouterProps {
basename?: string,
children?: React.ReactNode,
history: BrowserHistory
}


interface CustomRouterState {
action: Action,
location: Location
}


export default class CustomBrowserRouter extends React.Component<CustomRouterProps, CustomRouterState> {
constructor(props: CustomRouterProps) {
super(props);
this.state = {
action: props.history.action,
location: props.history.location
};


React.useLayoutEffect(() => props.history.listen(this.setState), [props.history]);
}


render() {
return (
<Router
basename={this.props.basename}
children={this.props.children}
location={this.state.location}
navigationType={this.state.action}
navigator={this.props.history}
/>
);
}
}

使用 CustomBrowserRouter:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { createBrowserHistory } from "history";
import CustomBrowserRouter from './CustomRouter/CustomBrowserRouter';


let history = createBrowserHistory();


ReactDOM.render(
<React.StrictMode>
<CustomBrowserRouter history={history}>
<App />
</CustomBrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);

不能完全让@Reid Nantes 版本运行,所以将它转换为一个功能性组件,它工作得很好

import React from "react";
import { BrowserHistory, Action, Location } from "history";
import { Router } from "react-router-dom";


interface CustomRouterProps {
basename?: string;
children?: React.ReactNode;
history: BrowserHistory;
}


interface CustomRouterState {
action: Action;
location: Location;
}


export const CustomBrowserRouter: React.FC<CustomRouterProps> = (props: CustomRouterProps) => {
const [state, setState] = React.useState<CustomRouterState>({
action: props.history.action,
location: props.history.location,
});


React.useLayoutEffect(() => props.history.listen(setState), [props.history]);
return <Router basename={props.basename} children={props.children} location={state.location} navigationType={state.action} navigator={props.history} />;
};


Best to use a module:

let _navigate
export const navigate = (...args) => _navigate(...args)
export const useNavigateSync = () => {
_navigate = useNavigate()
}

在顶级组件中运行 useNavigateSync。 Import navigate anywhere within your code.

User useNavigate for react-router-dom v6

import {useNavigate} from 'react-router-dom';
const navigate = useNavigate();
navigate('/home')

参考@poyoman 解决方案,如果你正在寻找它们在 TypeScript 表单中的实现,你可以试试这个:

import React, { FC, useLayoutEffect, useState } from 'react';
import { Router, RouterProps } from 'react-router-dom';
import { MemoryHistory } from 'history';


interface CustomRouterProps extends Omit<RouterProps, 'location' | 'navigator'> {
history: MemoryHistory;
}


export const CustomRouter: FC<CustomRouterProps> = ({ basename, children, history }) => {
const [state, setState] = useState<Pick<MemoryHistory, 'action' | 'location'>>({
action: history.action,
location: history.location,
});


useLayoutEffect(() => history.listen(setState), [history]);


return (
<Router
basename={basename}
children={children}
location={state.location}
navigationType={state.action}
navigator={history}
/>
);
};


可以在类似这样的课程中使用道具: 基于 Github 上的 Timdorr’s答案

Use the below prop in a class method:

this.props.navigate("/about")

路线包装如下:

// Routes in app.js
import MovieForm from "./components/movieForm";
import ElementWrapper from "./components/elementWrapper";


<Route path="/movies/new" element={<ElementWrapper routeElement={MovieForm} />} />


// i.e. specific to this question:
function getElement(route) {
return <ElementWrapper routeElement={route} />
}
children: [
{ path: 'account', element: getElement(AccountView) },
{ path: 'customers', element: getElement(CustomerListView) },
{ path: 'dashboard', element: getElement(DashboardView) },
{ path: 'products', element: getElement(ProductListView) },
{ path: 'settings', element: getElement(SettingsView) }
]


// Wrapper in elementWrapper.jsx in /components
import React from "react";
import { useNavigate } from "react-router-dom";


const ElementWrapper = (props) => {
const navigator = useNavigate();
const Element = props.routeElement;


return <Element navigator={navigator} {...props} />;
};


export default ElementWrapper;

解决办法就是

在 v6中,应该重写这个应用程序以使用导航 API。大多数情况下,这意味着将 useHistory 更改为 useNavigate,并更改 history. push 或 history. place calsite。

    // This is a React Router v5 app
import { useHistory } from "react-router-dom";
        

function App() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<div>
<button onClick={handleClick}>go home</button>
</div>
);
}

看看这篇文章。 https://reactrouter.com/en/v6.3.0/upgrading/v5#use-usenavigate-instead-of-usehistory

// This is a React Router v6 app
import { useNavigate } from "react-router-dom";


function App() {
let navigate = useNavigate();
function handleClick() {
navigate("/home");
}
return (
<div>
<button onClick={handleClick}>go home</button>
</div>
);
}

navigate push and navigate return is not required.