Магазин Redux не обновился, компонент обновился - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть контейнер React для входа пользователя. Когда он монтируется, он выбирает некоторые сторонние скрипты и вставляет их на страницу (это создает виджет входа)

Фаза входа в систему состоит из двух частей, первая часть состоит в том, чтобы войти в стороннюю систему, после чего мне необходимо войти во вторую систему, используя полезную нагрузку первой.

Вкл. componentDidMount Я запускаю запрос на загрузку сторонних скриптов, здесь все хорошо.

Когда я нажимаю кнопку входа (это встроенный виджет, предоставленный сторонней организацией, который запускает обратный вызов, к которому мы можем подключиться, нет необходимости создавать виджет и т. Д.), Обратный вызов срабатывает, и мы получаем клиента жетон обратно, опять все хорошо здесь.

Часть, с которой у меня возникают проблемы с использованием этого токена клиента, я использую приставку, чтобы добавить его в магазин, внутри componentDidUpdate Затем я проверяю prevProps по текущим реквизитам, чтобы проверить токен, если он существует, я запускаю действие для входа во вторую систему. Я хотел, чтобы это действие не срабатывало несколько раз, поэтому после его запуска я добавляю в хранилище поле hasRequested, а затем проверяю это в componentDidUpdate, чтобы не вызывать его несколько раз.

Этот бит не работает, потому что у меня есть несколько экземпляров LoginContainer на странице, componentDidUpdate запускается несколько раз, и хранилище не обновляется вовремя со значением hasRequested, В результате я делаю несколько запросов API.

Кто-нибудь получил какие-либо идеи, как я могу иметь несколько экземпляров контейнера, но ограничить количество срабатываний действия при обновлении его реквизита?

Пример кода ниже

LoginContainer

class LoginContainer extends Component {
  /**
   * componentDidMount
   */
  componentDidMount () {
    if (!this.props.thirdPartyCode.hasRequested) {
      this.props.fetchThirdPartySriptsAndLoad();
    }
  }

  /**
   * componentDidUpdate
   */
  componentDidUpdate (prevProps) {
    if (
      prevProps.authentication.customerToken !== this.props.authentication.customerToken
      && !this.props.authentication.hasRequested
    ) {
      this.props.authenticateUserWithSecondSystem();
    }
  }

Аутентификационный редуктор

import {
  SECOND_SYSTEM_AUTHENTICATE_REQUEST,
  SECOND_SYSTEM_AUTHENTICATE_SUCCESS,
  SECOND_SYSTEM_AUTHENTICATE_FAILURE,
} from 'actions/authentication/authentication-actions';

export const defaultState = {
  isFetching: false,
  hasRequested: false,
  error: '',
  customerToken: ''
};

/**
 * Reducer for authentication
 * @param {Object} state
 * @param {Object} action
 * @returns {Object} updated state
 */
export default function (state = defaultState, action) {
  switch (action.type) {
    case SECOND_SYSTEM_AUTHENTICATE_REQUEST:
      return Object.assign({}, state, {
        isFetching: true,
        hasRequested: true
      });
    case SECOND_SYSTEM_AUTHENTICATE_SUCCESS:
      return Object.assign({}, state, {
        isFetching: false
      });

Аутентификационные действия

export const SECOND_SYSTEM_AUTHENTICATE_REQUEST = 'SECOND_SYSTEM_AUTHENTICATE_REQUEST';
export const SECOND_SYSTEM_AUTHENTICATE_SUCCESS = 'SECOND_SYSTEM_AUTHENTICATE_SUCCESS';
export const SECOND_SYSTEM_AUTHENTICATE_FAILURE = 'SECOND_SYSTEM_AUTHENTICATE_FAILURE';

/**
 * Request Authenticate
 * @returns {{type: string}}
 */
function requestSecondSystemAuthentication () {
  return {
    type: SECOND_SYSTEM_AUTHENTICATE_REQUEST
  };
}

/**
 * Authenticate Success
 * @param {Object} data - response data
 * @returns {{type: string}}
 */
function secondSystemAuthenticateSuccess (data) {
  return {
    type: SECOND_SYSTEM_AUTHENTICATE_SUCCESS,
    data
  };
}

/**
 * Post Authenticate
 * @returns {Function} - action creator
 */
export function authenticateUserWithSecondSystem (authenticationToken) {
  return dispatch => {
    dispatch(requestSecondSystemAuthentication());

    ApiService.post('/api/authenticate', authenticationToken)
      .then(payload => dispatch(secondSystemAuthenticateSuccess(payload)))
}

1 Ответ

0 голосов
/ 15 ноября 2018

В итоге я решил, что пытаюсь сделать его слишком сложным, я выбрал одно действие с именем authenticateUser, которое вызывается по щелчку и обрабатывает логику для входа в систему первому провайдеру, а затем второму.

...