Sto costruendo un'app React/Redux utilizzando il middleware redux-thunk per creare e gestire le richieste Ajax. Ho un particolare thunk che viene sparato abbastanza spesso, e vorrei cancellare tutte le richieste Ajax precedentemente avviate prima di spararne una nuova. È possibile?Annullamento dell'azione asincrona precedente utilizzando redux-thunk
risposta
Un approccio sarebbe quello di contrassegnare quelle richieste come cancellate dando loro id casuali e controllando il suo stato prima di gestire il risultato.
Il modo per farlo è assegnare un id casuale per questa chiamata nella prima spedizione (all'interno del thunk) e controllarlo nel riduttore prima di gestire il risultato.
const actionId = Math.random();
dispatch({type: AJAX_LOAD_CONST, id:actionId })
Quando si desidera annullare tutte le richiesta di utilizzare
dispatch({type:HANDLE_AJAX_RESPONSE, id:actionId, results: json })
Quando si desidera gestire i risultati non dimenticate di inviare l'id che si u
e in il riduttore ha qualcosa di simile:
function reducer(state = initialState, action) {
switch (action.type) {
case actions.AJAX_LOAD_CONST:
return Object.assign({}, state, { ajax: state.ajax.concat(action.id) });
case actions.CANCEL_ALL_AJAX:
return Object.assign({}, state, { ajax: [] });
case actions.HANDLE_AJAX_RESPONSE:
if (state.ajax.includes(action.id) {
//return state reduced with action.results here
}
return state;
}
}
Se si utilizza XMLH ttpRequest o uno dei suoi wrapper (JQuery?) puoi anche memorizzare le richieste e chiamare request.abort(). se usi la nuova API di recupero non hai questo lusso in quanto le promesse mancano di questo comportamento.
Puoi far sì che il tuo creatore di azioni restituisca la promessa, verrà restituito dalla funzione di invio, quindi sarà possibile annullarlo. Ecco un esempio:
Azione creatore
function doSomething() {
return (dispatch) => {
return $.ajax(...).done(...).fail(...);
}
}
Il componente
componentDidMount(){
this.previousPromise = this.props.dispatch(doSomething());
}
somefnct() {
this.previousPromise.abort();
}