[英]using history with react-router-dom v6
我使用react-router-dom
version 6
,当我使用this.props.history.push('/UserDashboard')
它不起作用。 我把它改成
const history = createBrowserHistory();
history.push('/UserDashboard')
但我仍然有一个问题,当我想重定向到/UserDashboard
,只是链接发生了变化,而页面仍然是第一个??
有什么帮助吗??**
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);
}
})
}
我的 routes.js 文件:
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;
在 react-router-dom v6 中,您需要使用useNavigate而不是 useHistory。
请参阅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>
);
}
基于 react-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>
我们都知道 react-router-dom v6 中不再有 { useHistory } 之类的东西。 有更好的方法来完成 useHistory 的工作。
首先导入 useNavigate...
import { useNavigate } from 'react-router-dom';
然后在导入后执行此操作
function Test() {
const history = useNavigate();
function handleSubmit(e) {
e.preventDefault();
history('/home');
}
return (
<form onSubmit={handleSubmit}>
<button>Subimt</button>
</form>
)
}
Reactjs v6 带有 useNavigate 而不是 useHistory。
=> 首先,你必须像这样导入它: import {useNavigate} from 'react-router-dom'。
=> 那么你只能在这样的反应功能组件下使用它:
常量导航 = useNavigate() ;
=> 然后你想导航哪条路线,只需像这样输入路线名称:
导航(“/关于”);
例如:如果你想在点击一个按钮后导航到关于页面。那么你应该把
在此 onClick 事件下导航(“/about”) :
<button onClick = {()=>navigate("/about")}>转到关于页面
谢谢。
Typescript CustomBrowserRouter 基于@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}
/>
);
}
}
使用自定义浏览器路由器:
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')
);
如果您仍在 react v6+ 中使用 class 组件,另一种解决方案是将新的 Navigation object 作为历史记录注入。 这解决了无法在 class 组件中使用navigate()
的讨厌问题,尽管您将来应该尝试远离 class 组件。 我发现自己处于这种困境中,代码库很大,我相信其他人仍然如此。
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()} />
);
无法完全让@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} />;
};
最好使用一个模块:
let _navigate
export const navigate = (...args) => _navigate(...args)
export const useNavigateSync = () => {
_navigate = useNavigate()
}
在您的顶级组件中运行useNavigateSync
。 导入在代码中的任何位置navigate
。
解决方案是
在 v6 中,应重写此应用程序以使用导航 API。大多数情况下,这意味着将 useHistory 更改为 useNavigate 并更改 history.push 或 history.replace callsite。
// 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>
);
}
不需要导航push
和导航return
。
参考@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}
/>
);
};
可以在这样的类中使用道具:基于 timdorr 对Github 的回答
在 class 方法中使用以下道具:
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;
import {useNavigate} from 'react-router-dom'
class EmployeeComponent extends Component {
constructor(props) {
const { navigate } = this.props;
this.saveEmployee= this.saveEmployee.bind(this);
}
saveEmployee=(e) => {
e.preventDefault()
this.props.navigate("/employees")
}
}
export default function(props) {
const navigate = useNavigate();
return <EmployeeComponent {...props} navigate={navigate} />;
}
您可以尝试导入react-router-dom
useHistory
(版本 6)
import {useNavigate} from 'react-router-dom';
const navigate = useNavigate();
navigate('/home')
您可以使用中描述的解决方案
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} />; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.