[英]this.props.history.push() is changing the URL but not doing the action to the next page
我正在使用 react-router v6。 在登錄頁面的身份驗證 function (singIn) 中,我調用了 history.push。 URL 發生變化,但不執行移動到正確頁面的操作,而是保留在登錄頁面中。 身份驗證正在工作,如果我單擊 URL 並按“Enter”,身份驗證后,頁面仍然會推送。
我的 Index.jsx (根)
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import RoutesController from './routes';
ReactDOM.render(
<React.StrictMode>
<RoutesController />
</React.StrictMode>,
document.getElementById('root')
);
我的 routes.js(路由控制器):
import React from 'react';
import { BrowserRouter as Router, Routes, Route, useNavigate } from 'react-router-dom'
import HomePage from './App/pages/HomePage'
import UsersPage from './App/pages/UsersPage'
import Login from './App/pages/Login'
import PrivateRoute from './Auth'
import { createBrowserHistory } from "history";
const customHistory = createBrowserHistory();
function RoutesController() {
return (
<Router>
<Routes>
<Route path="/" element={<Login history={customHistory}/>} />
<Route path="/home" element={<PrivateRoute />}>
<Route path="" element={<HomePage />} />
</Route>
<Route path="/users" element={<PrivateRoute />}>
<Route path="" element={<UsersPage />} />
</Route>
<Route path="*" element={<h1>NOT FOUND</h1>} />
</Routes>
</Router>
)
}
export default RoutesController
我的登錄.jsx:
import React, { Component } from "react";
import Wrapper from "../../../components/Wrapper";
import "./style.css"
import logo from "../../../assets/icons/logotipo_semfundo.png"
import Button from "@material-ui/core/Button";
import { MdEmail, MdLock } from "react-icons/md"
class Login extends Component {
constructor(props) {
super(props)
this.state = {
message: '',
}
}
signIn = () => {
const data = { email: this.email, password: this.password }
const requestInfo = {
method: 'POST',
body: JSON.stringify(data),
headers: new Headers({
'Content-Type': 'application/json'
}),
}
fetch('http://localhost:3000/api/login', requestInfo).then(response => {
if (response.ok) {
return response.json()
}
throw new Error('Login Inválido...')
}).then(token => {
localStorage.setItem('accessToken', token)
this.props.history.push({pathname: "/home", message: "Ok"})
return
}
).catch(e => (this.setState({ message: e.message })))
}
render() {
localStorage.removeItem('accessToken')
return (
<Wrapper className="login">
<Wrapper className="login-img">
<img src={logo} alt="logo" />
</Wrapper>
<Wrapper className="login-form">
<h1 className="h1" >Login</h1>
{
this.state.message !== '' ? (
<span color="black">{this.state.message}</span>
) : ''
}
<form id="loginForm">
<Wrapper>
<Wrapper>
<MdEmail />
<input
id="email"
type="text"
name="email"
placeholder="Digite um E-mail"
onChange={e => this.email = e.target.value}
></input>
</Wrapper>
<Wrapper>
<MdLock />
<input
id="password"
type="password"
name="password"
placeholder="Senha"
onChange={e => this.password = e.target.value}
></input>
</Wrapper>
<Wrapper>
<Button
// label="Submit"
// type="submit"
// form="loginForm"
onClick={() => this.signIn()}
color="primary"
>
Entrar
</Button>
</Wrapper>
</Wrapper>
</form>
</Wrapper>
</Wrapper>
)
}
}
export default Login
認證頁面:
import React from 'react'
import { Navigate, Outlet } from 'react-router-dom'
const isAuth = () => {
if (localStorage.getItem('accessToken') !== null) {
return true
}
return false
}
const PrivateRoute = () => {
return (
isAuth() ? <Outlet />
: <Navigate
to={{
pathname: '/',
state: { message: 'Usuário não autorizado' }
}}
/>
)
}
export default PrivateRoute
在react-router-dom
v6 中,更高級別的路由器組件維護自己的內部history
引用,因此通過在RoutesController
中創建自己的歷史記錄並將其傳遞給Login
組件,它不會使用與路由器相同的歷史記錄 object。
除此之外,RRDv6 也不再公開history
object 而是公開navigate
function以用於命令式導航。 換句話說,而不是history.push("/newpath")
它被簡單地替換為navigate("/newpath")
。
另一個問題是Navigate
組件沒有使用 object 作為to
屬性。 state
現在是一級道具。
您有幾個選項或它們的組合可以從Login
組件訪問導航,但最簡單和更直接的是將Login
轉換為 React function 組件並使用useNavigate
掛鈎來訪問導航。
import { useNavigate } from 'react-router-dom';
const Login = () => {
const navigate = useNavigate(); // <-- call hook to get navigate function
const [message, setMessage] = React.useState('');
const [email, setEmail] = React.useState('');
const [password, setPassword] = React.useState('');
const signIn = () => {
const data = { email, password };
const requestInfo = {
method: 'POST',
body: JSON.stringify(data),
headers: new Headers({
'Content-Type': 'application/json'
}),
};
fetch('http://localhost:3000/api/login', requestInfo)
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Login Inválido...');
})
.then(token => {
localStorage.setItem('accessToken', token);
navigate("/home", { state: { message: "Ok" } }); // <-- navigate to new path
})
.catch(e => {
localStorage.removeItem('accessToken');
setMessage(e.message);
});
}
}
return (
<Wrapper className="login">
<Wrapper className="login-img">
<img src={logo} alt="logo" />
</Wrapper>
<Wrapper className="login-form">
<h1 className="h1">Login</h1>
{message && <span color="black">{message}</span>}
<form id="loginForm">
<Wrapper>
<Wrapper>
<MdEmail />
<input
id="email"
type="text"
name="email"
placeholder="Digite um E-mail"
onChange={e => setEmail(e.target.value)}
/>
</Wrapper>
<Wrapper>
<MdLock />
<input
id="password"
type="password"
name="password"
placeholder="Senha"
onChange={e => setPassword(e.target.value)}
/>
</Wrapper>
<Wrapper>
<Button
// label="Submit"
// type="submit"
// form="loginForm"
onClick={signIn}
color="primary"
>
Entrar
</Button>
</form>
</Wrapper>
</Wrapper>
);
};
對於PrivateRoute
組件,將 state 作為頂級道具。
<Navigate
to='/'
state={{ message: 'Usuário não autorizado' }}
/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.