ReactJS - 状态更改后重定向到专用路由
ReactJS - Redirect to private route after state change
我在 Express 中设置了一个登录路由,使用它时,它将设置我的应用程序的全局状态(使用 Context API),以包括用户 ID 和由 JSONWebToken 生成的令牌。
为了能够为用户加载待办事项,您需要有一个有效的令牌,当我在执行 API 请求时在 headers 中发送它时有效。使用 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
属性,您可以在 post.
的最后一个代码块中看到它是如何更改的
这是我的 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 的新手,所以非常感谢任何帮助。提前致谢!
我使用 react-router
中的 withRouter()
解决了这个问题,然后将历史推送到私有路由。
在此处阅读更多相关信息:
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md
我在 Express 中设置了一个登录路由,使用它时,它将设置我的应用程序的全局状态(使用 Context API),以包括用户 ID 和由 JSONWebToken 生成的令牌。
为了能够为用户加载待办事项,您需要有一个有效的令牌,当我在执行 API 请求时在 headers 中发送它时有效。使用 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
属性,您可以在 post.
这是我的 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 的新手,所以非常感谢任何帮助。提前致谢!
我使用 react-router
中的 withRouter()
解决了这个问题,然后将历史推送到私有路由。
在此处阅读更多相关信息: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md