我已经在Express中设置了一个登录路由,使用该路由时,它将设置我的应用程序的全局状态(使用Context API),以包括由JSONWebToken生成的用户ID和令牌。
要能够为用户加载待办事项,您需要有一个有效的令牌,该令牌在执行API请求时在标头中发送时就可以使用。使用Axios执行此操作时,状态也会被更新,但问题是我不知道如何(或如何获得最佳方式)转发到受保护的路由。
这是我的App.js,其中包含我的Welcome
和Todo
组件的路由。在Welcome
内部,有一个Login
组件,用于更新AppContext以包含用户ID和jsonwebtoken。
import React, { useContext } from 'react'
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom'
import { Switch } from 'react-router'
import TodoApp from './components/TodoApp/TodoApp'
import Welcome from './components/Welcome/Welcome'
import TodoProvider from './components/TodoApp/TodoContext'
import { AppContext } from './AppContext'
export default function App () {
const context = useContext(AppContext)
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props =>
context.loggedIn ? <Component {...props} /> : <Redirect to="/" />
}
/>
)
return (
<Router>
<Switch>
<Route exact path="/" component={Welcome} />
<TodoProvider>
<PrivateRoute exact path="/todo" component={TodoApp} />
</TodoProvider>
</Switch>
</Router>
)
}
请注意它检查的context.loggedIn
属性,您可以在本文的最后一个代码块中看到它的变化。
这是我的Login
组件,位于简单的Welcome
组件中
import React, { useState, useContext } from 'react'
import { AppContext } from '../../../AppContext'
export default function Login (props) {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const context = useContext(AppContext)
const handleSubmit = async e => {
e.preventDefault()
try {
// Method which logs in using the /api/login route, and returns users ID and token to the global state (context)
await context.handleLogin(email, password)
} catch {
throw Error('Login error')
}
}
return (
<form handleSubmit={handleSubmit}>
<div className="input-wrapper">
<label htmlFor="email" />
<input
type="text"
id="login_email"
placeholder="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
</div>
<div className="input-wrapper">
<label htmlFor="password" />
<input
type="password"
id="login_password"
placeholder="password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
</div>
<div className="input-wrapper">
<button
type="submit"
onClick={handleSubmit}
>
Log in
</button>
</div>
</form>
)
}
最后,方法context.handleLogin
更新状态以包含用户ID和令牌。取自AppContext.js
handleLogin = (email, password) => {
axios
.post('http://localhost:4000/api/login/', {
email,
password
})
.then(response => {
this.setState({
loggedIn: response.httpStatus === 200,
userID: response.data.data.user._id,
token: response.data.data.token
})
})
.catch(err => {
this.setState({
httpStatus: err.response.status,
loginError: 'Incorrect email/password'
})
})
}
我是React的新手,所以我们将不胜感激。预先感谢!
答案 0 :(得分:0)
我通过使用withRouter()
中的react-router
,然后将历史记录推到专用路线来解决了此问题。
在此处阅读有关此内容的更多信息: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md