Qual è il modo migliore per affrontare un errore di recupero nel ridurre la reazione?

Ho un riduttore per i Clienti, un altro per AppToolbar e altri …

Ora diciamo che ho creato un'azione di recupero per eliminare il client e, se non riesco, ho il codice nel riduttore Clienti che dovrebbe fare qualche cosa, ma voglio anche visualizzare qualche errore globale in AppToolbar.

Ma i riduttori Clienti e AppToolbar non condividono la stessa parte dello Stato e non posso creare una nuova azione nel riduttore.

Quindi, come suppongo di mostrare errore globale? Grazie

UPDATE 1:

Mi dimentico di menzionare che uso este devstack

AGGIORNAMENTO 2: Ho scritto la risposta di Eric come corretta, ma devo dire che la soluzione che sto usando in este è più simile alla combinazione di risposta di Eric e Dan … Devi solo trovare quello che ti si adatta meglio nel tuo codice .. .

Se si desidera avere il concetto di "errori globali", è ansible creare un riduttore di errors che può ascoltare azioni di addError, removeError ecc. Quindi, puoi agganciare l'tree di stato Redux a state.errors e visualizzarli where è opportuno.

Ci sono diversi modi in cui si potrebbe avvicinarsi, ma l'idea generale è che gli errori / messaggi globali <AppToolbar /> il proprio riduttore a vivere completamente separati da <Clients /> / <AppToolbar /> . Naturalmente se uno di questi componenti necessita di accesso a errors è ansible passare gli errors fino a loro come un supporto where necessario.

Aggiornamento: Esempio di codice

Ecco un esempio di cosa potrebbe sembrare se wheressi passare gli errori " errors globali" nel tuo livello superiore <App /> e renderlo costantemente (se esistono errori). Utilizzando la function di reactjs-redux per connect il componente <App /> a alcuni dati.

 // App.js // Display "global errors" when they are present function App({errors}) { return ( <div> {errors && <UserErrors errors={errors} /> } <AppToolbar /> <Clients /> </div> ) } // Hook up App to be a container (react-redux) export default connect( state => ({ errors: state.errors, }) )(App); 

E per quanto riguarda il creatore d'azione, avrebbe inviato ( ridx-thunk ) il fallimento del successo secondo la risposta

 export function fetchSomeResources() { return dispatch => { // Async action is starting... dispatch({type: FETCH_RESOURCES}); someHttpClient.get('/resources') // Async action succeeded... .then(res => { dispatch({type: FETCH_RESOURCES_SUCCESS, data: res.body}); }) // Async action failed... .catch(err => { // Dispatch specific "some resources failed" if needed... dispatch({type: FETCH_RESOURCES_FAIL}); // Dispatch the generic "global errors" action // This is what makes its way into state.errors dispatch({type: ADD_ERROR, error: err}); }); }; } 

Mentre il tuo riduttore potrebbe semplicemente gestire una serie di errori, aggiungere o rimuovere le voci in modo appropriato.

 function errors(state = [], action) { switch (action.type) { case ADD_ERROR: return state.concat([action.error]); case REMOVE_ERROR: return state.filter((error, i) => i !== action.index); default: return state; } } 

La risposta di Erik è corretta, ma vorrei aggiungere che non devi sparare azioni separate per aggiungere errori. Un approccio alternativo è quello di avere un riduttore che gestisce qualsiasi azione con un field di error . Questa è una questione di scelta personale e convenzione.

Ad esempio, da un esempio real-world Redux che ha la gestione degli errori:

 // Updates error message to notify about the failed fetches. function errorMessage(state = null, action) { const { type, error } = action if (type === ActionTypes.RESET_ERROR_MESSAGE) { return null } else if (error) { return action.error } return state } 

L'approccio che attualmente esegue per alcuni errori specifici (validation dell'entrata degli utenti) è che i miei sottoregolatori lanciano un'exception, la prendono nel mio riduttore radice e lo collegano all'object d'azione. Poi ho una saga di ridx che esamina gli oggetti di azione per un errore e aggiorna l'tree di stato con i dati di errore in quel caso.

Così:

 function rootReducer(state, action) { try { // sub-reducer(s) state = someOtherReducer(state,action); } catch (e) { action.error = e; } return state; } // and then in the saga, registered to take every action: function *errorHandler(action) { if (action.error) { yield put(errorActionCreator(error)); } } 

E poi aggiungendo l'errore all'tree di stato è come descrive Erik.

Lo uso abbastanza sparingmente, ma mi impedisce di duplicare la logica che appartiene legittimamente al riduttore (in modo che possa proteggere da uno stato invalido).

È ansible utilizzare il client HTTP axios. Ha già implementato la function Interceptors. È ansible intercettare richieste o risposte prima di essere gestite da allora o catturare.

https://github.com/mzabriskie/axios#interceptors

 // Add a request interceptor axios.interceptors.request.use(function (config) { // Do something before request is sent return config; }, function (error) { // Do something with request error return Promise.reject(error); }); // Add a response interceptor axios.interceptors.response.use(function (response) { // Do something with response data return response; }, function (error) { // Do something with response error return Promise.reject(error); });