Как в React’e и Redux-Saga при диспатче action’a дождаться ответа и использовать эти данные дальше?

В React и Redux-Saga существует несколько способов дождаться ответа после диспатча экшна и использовать полученные данные дальше. Рассмотрим некоторые из них.

Первый способ - использование асинхронных функций. Вы можете использовать асинхронные функции, такие как async/await, для дожидания ответа от запроса или другой асинхронной операции.

Ваш компонент React может содержать метод, в котором вы диспатчите экшн, а затем ожидаете ответ:

import { useSelector, useDispatch } from 'react-redux';
import { fetchData } from '../actions';

function MyComponent() {
  const data = useSelector(state => state.data);
  const dispatch = useDispatch();

  async function handleFetchData() {
    const response = await dispatch(fetchData());
    // Здесь можно использовать полученные данные, например:
    console.log(response.payload);
  }

  return (
    <button onClick={handleFetchData}>Загрузить данные</button>
  );
}

Здесь функция async handleFetchData является асинхронной, что позволяет использовать await для ожидания ответа диспатча экшна fetchData(). Затем вы можете использовать полученные данные после завершения операции.

Второй способ - использование саг (saga). Redux-Saga предоставляет библиотеку для управления побочными эффектами в приложении, такими как асинхронные запросы. Вы можете создать сагу, которая будет следить за определенными экшнами и выполнять необходимые побочные эффекты.

Пример использования саги для дожидания ответа и использования данных:

import { put, takeLatest, call } from 'redux-saga/effects';
import { fetchDataSuccess, fetchDataFailure } from '../actions';
import { API } from '../api';

function* fetchDataSaga() {
  try {
    const response = yield call(API.fetchData);
    yield put(fetchDataSuccess(response.data));
  } catch (error) {
    yield put(fetchDataFailure(error));
  }
}

function* watchFetchData() {
  yield takeLatest('FETCH_DATA', fetchDataSaga);
}

export default watchFetchData;

Здесь fetchDataSaga - это сага, которая будет вызываться при каждом диспатче экшна 'FETCH_DATA'. Внутри саги вы можете использовать функции yield, такие как call и put, чтобы выполнить асинхронные операции и диспатчить новые экшны.

Определение саги должно быть добавлено в корневой файл саг приложения:

import { all } from 'redux-saga/effects';
import watchFetchData from './watchFetchData';

export default function* rootSaga() {
  yield all([
    watchFetchData(),
    // Другие саги...
  ]);
}

Затем вы должны добавить корневую сагу в конфигурацию Redux приложения:

import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import rootSaga from './sagas';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);

export default store;

Теперь при каждом диспатче экшна 'FETCH_DATA' сага будет отлавливать этот экшн, выполнять необходимые операции и запускать диспатчи соответствующих экшнов в случае успешного выполнения или ошибки.

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