@Aleksey100

Как сделать экспорт в react\redux после запроса API?

Здравствуйте.

Пишу приложение на react\redux и есть у меня вот такой редьюсер

import axios from 'axios';

let initialState = [];

axios.defaults.headers['Authorization'] = `Bearer ` + sessionStorage.getItem('accessToken');

axios.get('/webchat/index')
.then((res) => {
      console.log(res.data);
      initialState = res.data;
   }
)
.catch(
   (err) => {
      console.log(err.response);
   }
);

console.log(initialState);

export default function(initialState, action) {
   return initialState;
}


Этот запрос выполняется сразу при загрузке страницы.

Проблема в том что export происходит раньше чем запрос и из-за этого экспортируется пустой initialState.

Как можно это исправить?

PS: Экспорт поместить внутрь then не получится, т.к. появляется ошибка что функция экспорта не может быть вложена.
  • Вопрос задан
  • 463 просмотра
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Сам вопрос поставлен вразрез с концепцией Redux, да и самой модульной концепцией JavaScript. Вам не надо пытаться экспортировать модуль после запроса, так делать нельзя. Вам надо задать начальное состояние и определить там ключи состояния isLoading, isError. При инициализации приложения произойдет запрос на сервер за данными и пока они не пришли isLoading будет иметь значение true, вы, в идеале, в этот момент должны показывать пользователю прелоадер.
Ну, а то что вы пытались сделать это в корне не правильно.

При использовании redux-thunk должно получится, что-то вроде:
import { fetchInitialDataApi } from './api';

const FETCH_INITIAL_DATA_REQUEST = 'FETCH_INITIAL_DATA_REQUEST';
const FETCH_INITIAL_DATA_SUCCESS = 'FETCH_INITIAL_DATA_SUCCESS';
const FETCH_INITIAL_DATA_ERROR = 'FETCH_INITIAL_DATA_ERROR';

const fetchInitialDataRequest = () => ({ type:  FETCH_INITIAL_DATA_REQUEST });
const fetchInitialDataSuccess = data => ({
  type:  FETCH_INITIAL_DATA_SUCCES,
  payload: data,
});
const fetchInitialDataError = error => ({
  type:  FETCH_INITIAL_DATA_ERROR,
  payload: error,
});

const fetchInitialData => async dispatch => {
  try {
    dispatch(fetchInitialDataRequest());
    const { data } = await fetchInitialDataApi();
    dispatch(fetchInitialDataSuccess(data));
  } catch error {
    dispatch(fetchInitialDataError(error));
  }
};

const initialState = {
  data: {},
  isLoading: false,
  isError: false,
  error: null,
};

export default function(state = initialState, action) {
  const { type, payload } = action;

  switch (type) {
    case FETCH_INITIAL_DATA_REQUEST:
      return {
        ...state,
        isLoading: true,
        isError: false,
        error: null,
      };
    case FETCH_INITIAL_DATA_SUCCESS:
      return {
        ...state,
        data: payload,
        isLoading: false,
      };
    case FETCH_INITIAL_DATA_ERROR:
      return {
        ...state,
        isLoading: false,
        isError: true,
        error: payload,
      };
  default:
    return state;
  }
}


Если же хотите получать начальные данные сразу и они статичные, то пишите их в шаблон страницы приложения в window._data и забирайте через reducer:
export default (state = window._data) => state;
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@vshvydky
Какой-то левый редьюсор, так не делают. Все запросы в экшен, когда результат асинхронный диспетч 3 состояний, запрос начат, запрос выполнен успешно или сбой, в интернете полно готовых примеров этого, гугли.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы