React Router v4:自定义 PrivateRoute 组件不断重新加载
React Router v4: custom PrivateRoute component keeps reloading
这是我的第一个问题,所以请饶了我吧。
我尝试了所有可能的研究,但我已经放弃了。
所以基本上我是在用 react-router v4 处理受保护的路由。在看了 Tyler Mcginnis 的 PrivateRoute 之后,我认为我在正确的轨道上,但没有。
我可以使用 requireUser
函数正确设置 isAuthenticated: true
,但 PrivateRoute 路由组件从未呈现。它总是重定向到 /login
。经过进一步调查,我意识到页面以某种方式刷新,因此将 isAuthenticated
设置回 false
此外,我没有使用 Redux。
哦,欢迎对我的代码提出任何批评。
请帮忙
/App.js
class App extends Component {
constructor() {
super()
this.state = {
isAuthenticated: false,
user: {
username: ''
}
}
}
requireUser = (userData) => {
console.log('userData', userData);
if(userData) {
this.setState({
isAuthenticated: true,
user: {
username: userData.username
}
})
}
}
render() {
return (
<Router>
<div>
<Navbar />
<Route exact path='/' component={Landing} />
<Route path='/register' component={Register} />
<Route path='/login' render={(props) => {
return <Login {...props} requireUser={this.requireUser} />
}} />
<PrivateRoute path='/search' component={SearchBar} auth={this.state.isAuthenticated} />
</div>
</Router>
);
}
}
export default App;
/PrivateRoute.js
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
const PrivateRoute = ({ component: Component, auth, path, ...rest}) => {
return <Route {...rest} path='/search' render={(props) => {
console.log(auth);
if(auth) {
return (
<Component {...props} />
)
} else {
return (
<Redirect to='/login' />
)
}
}} />
}
export default PrivateRoute
编辑:添加到我的登录组件中
更新:我最终将 this.props.history.push('/search)
添加到我的 handleOnSubmit
函数
/Login.js
import React, { Component } from 'react'
import axios from 'axios'
import jwt_decode from 'jwt-decode'
class Login extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
}
}
handleOnChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
handleOnSubmit = (e) => {
// prevent page refresh
e.preventDefault()
// destructure state
const { email, password } = this.state
// assign to userData
const userData = { email, password }
// axios post /api/users/login
axios
.post('/api/users/login', userData)
.then((response) => {
// destructure
const { token } = response.data
const decoded = jwt_decode(token)
this.props.requireUser(decoded)
})
.catch((error) => {
console.log(error);
})
}
render() {
return (
<section className="section">
<div className="container">
<form>
<div className="field">
<label className="label">Email</label>
<div className="control">
<input
type="email"
placeholder="email"
className="input"
name='email'
onChange={this.handleOnChange}
/>
</div>
</div>
<div className="field">
<label className="label">Password</label>
<input
type="password"
placeholder="password"
className="input"
name='password'
onChange={this.handleOnChange}
/>
</div>
<div className="field">
<div className="control">
<button
onClick={this.handleOnSubmit}
type="submit"
className="button is-primary"
>Log In</button>
</div>
</div>
</form>
</div>
</section>
)
}
}
export default Login
你的代码看起来不错。问题是当您手动将地址栏更改为 /search
时,浏览器将被刷新。没有办法解决这个问题。
您也可以使用 Link
组件,其 to
属性值为 '/search'
,您的用户可以使用它来导航到搜索,或者您可以通过编程方式更改路径history
对象。
this.props.history.push('/search');
这是我的第一个问题,所以请饶了我吧。
我尝试了所有可能的研究,但我已经放弃了。
所以基本上我是在用 react-router v4 处理受保护的路由。在看了 Tyler Mcginnis 的 PrivateRoute 之后,我认为我在正确的轨道上,但没有。
我可以使用 requireUser
函数正确设置 isAuthenticated: true
,但 PrivateRoute 路由组件从未呈现。它总是重定向到 /login
。经过进一步调查,我意识到页面以某种方式刷新,因此将 isAuthenticated
设置回 false
此外,我没有使用 Redux。
哦,欢迎对我的代码提出任何批评。
请帮忙
/App.js
class App extends Component {
constructor() {
super()
this.state = {
isAuthenticated: false,
user: {
username: ''
}
}
}
requireUser = (userData) => {
console.log('userData', userData);
if(userData) {
this.setState({
isAuthenticated: true,
user: {
username: userData.username
}
})
}
}
render() {
return (
<Router>
<div>
<Navbar />
<Route exact path='/' component={Landing} />
<Route path='/register' component={Register} />
<Route path='/login' render={(props) => {
return <Login {...props} requireUser={this.requireUser} />
}} />
<PrivateRoute path='/search' component={SearchBar} auth={this.state.isAuthenticated} />
</div>
</Router>
);
}
}
export default App;
/PrivateRoute.js
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
const PrivateRoute = ({ component: Component, auth, path, ...rest}) => {
return <Route {...rest} path='/search' render={(props) => {
console.log(auth);
if(auth) {
return (
<Component {...props} />
)
} else {
return (
<Redirect to='/login' />
)
}
}} />
}
export default PrivateRoute
编辑:添加到我的登录组件中
更新:我最终将 this.props.history.push('/search)
添加到我的 handleOnSubmit
函数
/Login.js
import React, { Component } from 'react'
import axios from 'axios'
import jwt_decode from 'jwt-decode'
class Login extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
}
}
handleOnChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
handleOnSubmit = (e) => {
// prevent page refresh
e.preventDefault()
// destructure state
const { email, password } = this.state
// assign to userData
const userData = { email, password }
// axios post /api/users/login
axios
.post('/api/users/login', userData)
.then((response) => {
// destructure
const { token } = response.data
const decoded = jwt_decode(token)
this.props.requireUser(decoded)
})
.catch((error) => {
console.log(error);
})
}
render() {
return (
<section className="section">
<div className="container">
<form>
<div className="field">
<label className="label">Email</label>
<div className="control">
<input
type="email"
placeholder="email"
className="input"
name='email'
onChange={this.handleOnChange}
/>
</div>
</div>
<div className="field">
<label className="label">Password</label>
<input
type="password"
placeholder="password"
className="input"
name='password'
onChange={this.handleOnChange}
/>
</div>
<div className="field">
<div className="control">
<button
onClick={this.handleOnSubmit}
type="submit"
className="button is-primary"
>Log In</button>
</div>
</div>
</form>
</div>
</section>
)
}
}
export default Login
你的代码看起来不错。问题是当您手动将地址栏更改为 /search
时,浏览器将被刷新。没有办法解决这个问题。
您也可以使用 Link
组件,其 to
属性值为 '/search'
,您的用户可以使用它来导航到搜索,或者您可以通过编程方式更改路径history
对象。
this.props.history.push('/search');