У меня есть контейнер 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)))
}