Перенаправить пользователя с помощью React-Router 4 и Redux-Promise
У меня есть простой пример использования, который в среде React-Router 4 и Redux кажется довольно сложным.
Когда пользователь входит в систему, запускается действие обещания избыточности, которое возвращает токен API, дату истечения срока действия и некоторую другую информацию. Когда и если обещание выполнено, я бы хотел перенаправить пользователя на другую страницу.
Я не могу понять, как перенаправить пользователя программно, используя вышеупомянутую архитектуру. Я хочу сделать это в Action.js, но чувствую, что это можно сделать только в Reducers.js. Хотя я не уверен, даже как начать.
Наилучший способ, который я нашел до сих пор, - это иметь компонент Redirect в моем представлении и иметь обещание, устанавливающее состояние loggedIn в значение true, если для представления loggedIn значение true, то оно возвращает возвращаемое свойство перенаправления, которое затем перенаправляет пользователя на нужную страницу. Каким-то образом это кажется большим количеством дополнительного кода для простого варианта использования.
Любые советы будут полезны. Спасибо.
Action.js:
import axios from 'axios';
export function login(email, password) {
return {
type: 'LOGIN_USER',
payload: axios.post('http://localhost:3114/api/users/authenticate',
{
email,
password,
}),
};
}
Reducers.js
// Promise
// pending
// fulfilled
// rejected
const initalState = {
token: null,
expiryDate: '',
loading: false,
error: null,
};
// REDCUER
function loginReducer(state = initalState, action) {
switch (action.type) {
case 'LOGIN_USER_PENDING':
return { ...state, loading: true };
case 'LOGIN_USER_FULFILLED':
return {
...state,
loading: false,
token: action.payload.data.token,
expiryDate: action.payload.data.expires,
loggedIn: true,
};
case 'LOGIN_USER_REJECTED':
return { ...state, loading: false, error: `${action.payload}` };
default:
return state;
}
}
export default loginReducer;
LoginView.js
render() {
const { data, login, loggedIn } = this.props;
if (data.loggedIn) {
return <Redirect to="/users" push />;
}
return (
...
)
}
С уважением, Эмир
1 ответ
Я мог видеть isLoggedIn
в состоянии Redux, потенциально полезном на более позднем этапе (например, вы можете обернуть все маршруты / страницы, которые должны быть видны только зарегистрированным пользователям, в компоненте, который проверяет это isLoggedIn
и потенциально перенаправляет на страницу входа в систему), поэтому я бы не стал ничего менять там.
Но если вы все еще хотите найти другой способ обойти это, то можно перенаправить программно (без рендеринга компонента Redirect), используя history.push(newUrl)
или жеhistory.replace(newUrl)
, Но я не уверен, где вы бы это назвали. Наличие побочных эффектов в создателе действий кажется мне несколько менее странным по сравнению с наличием его в редукторе, поэтому, возможно, одной из возможностей будет сделать что-то вроде
import axios from 'axios';
// pushOnResolve would be something like () => push('mynew/url')
export function login(email, password, pushOnResolve) {
const promise = axios.post('http://localhost:3114/api/users/authenticate';
// it's possible to have several .then on a promise
// so this shouldn't interfere with
// the Redux-promise or the LOGIN_USER_FULFILLED reducer
promise.then(pushOnResolve);
return {
type: 'LOGIN_USER',
payload: promise,
{
email,
password,
}),
};
}