React Router 在保留历史记录的同时返回两页

React Router going back two pages while preserving history

当有人试图访问 ex /account/dashboard 的受限路由时,我们需要要求他登录,然后将他重定向回 /account/dashboard 页面。我们的登录路径历史看起来像

使用 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

建议的