es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo administrar el estado complejo de Redux para diferentes llamadas asíncronas?

Siempre he pensado en esta pregunta cuando tienes un escenario con una división de redux y deseas obtener múltiples APIs diferentes o realizar algunas llamadas asíncronas en algunos eventos al mismo tiempo, ¿cómo construirías tu reductor y el estado de redux?

Permíteme explicar un escenario específico:

Imagina que quiero obtener el resultado de 2 APIs y tengo este estado:

{
 data1: null,
 data2: null,
 loading: false,
 error: false,
}

Y quiero realizar dos llamadas para obtener los datos cuando se monte el componente de React, ¿debería declarar dos variables de carga para estas dos llamadas o qué? ¿cuál es la mejor práctica en este tipo de situaciones? También puedes imaginar dos o tres eventos de clic diferentes que llamen a una API Fetch de forma asíncrona.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Cuando estés trabajando en un escenario en el que necesites obtener múltiples APIs o hacer múltiples llamadas asíncronas simultáneamente, se recomienda utilizar un middleware de Redux como Redux-Saga.

    En el escenario dado, puedes definir una acción diferente para cada llamada a la API o evento, y luego usar un saga para manejar estas acciones. En el saga, puedes usar el efecto call para hacer la llamada a la API y actualizar el estado en consecuencia.

    Por ejemplo, podrías definir las siguientes acciones:

    const FETCH_DATA_1 = 'FETCH_DATA_1';
    const FETCH_DATA_2 = 'FETCH_DATA_2';
    const FETCH_DATA_START = 'FETCH_DATA_START';
    const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
    const FETCH_DATA_ERROR = 'FETCH_DATA_ERROR';
    

    Luego, puedes definir un saga para manejar estas acciones:

    function* fetchData(action) {
      try {
        yield put({ type: FETCH_DATA_START });
        const data = yield call(api.GetData, action.payload);
        yield put({ type: FETCH_DATA_SUCCESS, payload: data });
      } catch (error) {
        yield put({ type: FETCH_DATA_ERROR, payload: error });
      }
    }
    
    function* mySaga() {
      yield takeEvery(FETCH_DATA_1, fetchData);
      yield takeEvery(FETCH_DATA_2, fetchData);
      // añade más listeners de eventos
    }
    

    El estado puede ser actualizado de la siguiente manera:

    const initialState = {
      data1: null,
      data2: null,
      loading: false,
      error: false,
    }
    
    function myReducer(state = initialState, action) {
      switch(action.type) {
        case FETCH_DATA_START:
          return { ...state, loading: true }
        case FETCH_DATA_SUCCESS:
          if (action.payload.data1) {
            return { ...state, loading: false, data1: action.payload.data1 }
          }
          if (action.payload.data2) {
            return { ...state, loading: false, data2: action.payload.data2 }
          }
          // añade más casos
        case FETCH_DATA_ERROR:
          return { ...state, loading: false, error: true }
        default:
          return state
      }
    }
    

    Con este método, puedes manejar múltiples llamadas asíncronas y actualizar el estado según la respuesta de cada API. Con este enfoque, evitas tener múltiples estados de carga y tienes un control más granular sobre las actualizaciones del estado.

Comments are closed.