Перенаправить пользователя с помощью 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,
    }),
  };
}
Другие вопросы по тегам