Реагирующий маршрутизатор возвращается на две страницы назад с сохранением истории

#reactjs #redux #react-router-v4

#reactjs #сокращение #react-router-v4

Вопрос:

Когда кто-то пытается получить доступ к ограниченному маршруту, например /account/dashboard , нам нужно попросить его войти в систему, а затем перенаправить его обратно на /account/dashboard страницу. Наша история маршрута входа в систему выглядит следующим образом

  • / войти
  • / проверка-otp

Используя объект истории маршрутизатора React, как мне перенаправить пользователя обратно /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 amp;amp; !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))
        })
}
 

Комментарии:

1. Есть ли конкретная причина, по которой вы не сделали history.push('/account/dashboard') бы вместо того, чтобы вернуться на две страницы назад?

2. ну, потому что может быть много случаев, когда URL-адрес может отличаться. Он может посещать / аккаунт / заказы или он может посещать оформление заказа / корзину

3. может быть, сохранение местоположения пользователя до того, как оно было перенаправлено /login ? Это будет вариант? И затем history.push(initialLocation)

4. @ajmnz поэтому я сохраняю инициализацию в хранилище redux и пропускаю его обновление, когда пользователь находится на путях входа. Я не знаю, это больше похоже на взлом, не так ли?

5. Я имел в виду, что, как только пользователь получает сообщение account/dashboard , должна быть проверка, вошел ли пользователь в систему, верно? Если нет, он перенаправляется на /login . Почему бы не сохранить в хранилище Redux местоположение, куда пользователь был перенаправлен? Я не рассматриваю это как взлом, tbh. Для этого должен быть какой-то способ react-router, но atm я с ним не сталкивался

Ответ №1:

Поэтому, чтобы решить эту проблему, я создал отдельный компонент LinkItem и теперь буду использовать этот компонент для всех ссылок в моем приложении. Когда кто-то нажимает на ссылку, я устанавливаю переменную реферера в хранилище, и после того, как кто-то вошел в систему, я вижу, присутствует ли реферер, я перенаправляю на реферер, если нет, я перенаправляю на домашнюю страницу.

LinkItem

 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 amp;amp;
                    <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 amp;amp; !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