#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