React Router 在保留历史记录的同时返回两页
React Router going back two pages while preserving history
当有人试图访问 ex /account/dashboard
的受限路由时,我们需要要求他登录,然后将他重定向回 /account/dashboard
页面。我们的登录路径历史看起来像
- /登录
- /验证-otp
使用 React Router 的历史对象,我如何在用户成功登录后将其重定向回 /account/dashboard
。
验证 OTP 操作
export const verifyOTP = data => async (dispatch, getState) => {
const { userId, profileCompleted } = getState().user
await svysh.post(`/customer/verify-otp/${userId}`, { otp: Number(data) })
.then((response) => {
let verified = response.data.error ? false : true
let token = response.data.error ? null : response.data.data.access_token
let tokenExpiry = response.data.error ? null : Date.parse(response.data.data.expires_at)
let isSignedIn = token ? true : false
let errorCode = response.data.error ? response.data.code : null
dispatch({
type: actionTypes.VERIFY_OTP,
accessToken: token,
accessTokenExpiry: tokenExpiry,
verfied: verified,
isSignedIn: isSignedIn,
error: response.data.error,
errorCode: errorCode,
message: response.data.message
})
dispatch(setLoading(false))
if (verified && !profileCompleted) {
history.push('/complete-profile')
} else if (!verified) {
history.push('/verify')
} else {
window.history.go(-2)
}
})
.catch(error => {
console.log('Catch Error', error)
dispatch(setLoading(false))
})
}
因此,为了解决这个问题,我创建了一个单独的 LinkItem 组件,现在我的应用程序中的所有 link 都将使用该组件。当有人点击 link 时,我在商店中设置了一个引荐来源变量,并且在有人登录后,我查看引荐来源网址是否存在,如果不存在,我将重定向到引荐来源网址。
Link项目
import LinkItem from '../../../extras/LinkItem'
<LinkItem
to='/account/orders'
list='true'
text='Orders'
/>
Link 组件
import { ListItem } from '@material-ui/core'
class LinkItem extends React.Component {
handleReferrer() {
const { to } = this.props
this.props.setReferrer(to)
}
render() {
const { list, to, text } = this.props
return (
<>
{list &&
<ListItem
component='a'
disableGutters
href={to}
onClick={() => this.handleReferrer()}
>
{text}
</ListItem>
}
</>
)
}
}
验证 OTP 时重定向
export const verifyOTP = data => async (dispatch, getState) => {
const { userId, profileCompleted } = getState().user
const { referrer } = getState().global
await svysh.post(`/customer/verify-otp/${userId}`, { otp: Number(data) })
.then((response) => {
let verified = response.data.error ? false : true
let token = response.data.error ? null : response.data.data.access_token
let tokenExpiry = response.data.error ? null : Date.parse(response.data.data.expires_at)
let isSignedIn = token ? true : false
let errorCode = response.data.error ? response.data.code : null
dispatch({
type: actionTypes.VERIFY_OTP,
accessToken: token,
accessTokenExpiry: tokenExpiry,
verfied: verified,
isSignedIn: isSignedIn,
error: response.data.error,
errorCode: errorCode,
message: response.data.message
})
dispatch(setLoading(false))
if (verified && !profileCompleted) {
history.push('/complete-profile')
} else if (!verified) {
history.push('/verify')
} else {
if (referrer) {
history.push(referrer)
} else {
history.push('/')
}
}
})
.catch(error => {
console.log('Catch Error', error)
dispatch(setLoading(false))
})
}
编辑:
这种方法是由 @ajmnz
建议的
当有人试图访问 ex /account/dashboard
的受限路由时,我们需要要求他登录,然后将他重定向回 /account/dashboard
页面。我们的登录路径历史看起来像
- /登录
- /验证-otp
使用 React Router 的历史对象,我如何在用户成功登录后将其重定向回 /account/dashboard
。
验证 OTP 操作
export const verifyOTP = data => async (dispatch, getState) => {
const { userId, profileCompleted } = getState().user
await svysh.post(`/customer/verify-otp/${userId}`, { otp: Number(data) })
.then((response) => {
let verified = response.data.error ? false : true
let token = response.data.error ? null : response.data.data.access_token
let tokenExpiry = response.data.error ? null : Date.parse(response.data.data.expires_at)
let isSignedIn = token ? true : false
let errorCode = response.data.error ? response.data.code : null
dispatch({
type: actionTypes.VERIFY_OTP,
accessToken: token,
accessTokenExpiry: tokenExpiry,
verfied: verified,
isSignedIn: isSignedIn,
error: response.data.error,
errorCode: errorCode,
message: response.data.message
})
dispatch(setLoading(false))
if (verified && !profileCompleted) {
history.push('/complete-profile')
} else if (!verified) {
history.push('/verify')
} else {
window.history.go(-2)
}
})
.catch(error => {
console.log('Catch Error', error)
dispatch(setLoading(false))
})
}
因此,为了解决这个问题,我创建了一个单独的 LinkItem 组件,现在我的应用程序中的所有 link 都将使用该组件。当有人点击 link 时,我在商店中设置了一个引荐来源变量,并且在有人登录后,我查看引荐来源网址是否存在,如果不存在,我将重定向到引荐来源网址。
Link项目
import LinkItem from '../../../extras/LinkItem'
<LinkItem
to='/account/orders'
list='true'
text='Orders'
/>
Link 组件
import { ListItem } from '@material-ui/core'
class LinkItem extends React.Component {
handleReferrer() {
const { to } = this.props
this.props.setReferrer(to)
}
render() {
const { list, to, text } = this.props
return (
<>
{list &&
<ListItem
component='a'
disableGutters
href={to}
onClick={() => this.handleReferrer()}
>
{text}
</ListItem>
}
</>
)
}
}
验证 OTP 时重定向
export const verifyOTP = data => async (dispatch, getState) => {
const { userId, profileCompleted } = getState().user
const { referrer } = getState().global
await svysh.post(`/customer/verify-otp/${userId}`, { otp: Number(data) })
.then((response) => {
let verified = response.data.error ? false : true
let token = response.data.error ? null : response.data.data.access_token
let tokenExpiry = response.data.error ? null : Date.parse(response.data.data.expires_at)
let isSignedIn = token ? true : false
let errorCode = response.data.error ? response.data.code : null
dispatch({
type: actionTypes.VERIFY_OTP,
accessToken: token,
accessTokenExpiry: tokenExpiry,
verfied: verified,
isSignedIn: isSignedIn,
error: response.data.error,
errorCode: errorCode,
message: response.data.message
})
dispatch(setLoading(false))
if (verified && !profileCompleted) {
history.push('/complete-profile')
} else if (!verified) {
history.push('/verify')
} else {
if (referrer) {
history.push(referrer)
} else {
history.push('/')
}
}
})
.catch(error => {
console.log('Catch Error', error)
dispatch(setLoading(false))
})
}
编辑: 这种方法是由 @ajmnz
建议的