A
A
Alexey1002018-01-31 10:46:55
JavaScript
Alexey100, 2018-01-31 10:46:55

How to make export to react\redux after API request?

Hello.
I am writing an application on react \ redux and I have such a reducer

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;
}

This request is executed immediately when the page is loaded.
The problem is that the export happens before the request and because of this, an empty initialState is exported .
How can this be fixed?
PS: Export can't be placed inside then , because an error appears that the export function cannot be nested.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton Spirin, 2018-01-31
@Aleksey100

The very question is posed against the concept of Redux , and indeed the very modular concept of JavaScript . You don't have to try to export the module after the request, you can't do that. You need to set the initial state and define the isLoading , isError state keys there . When the application is initialized, a request will be made to the server for the data, and until they arrive, isLoading will be set to true , you, ideally, should show the user a preloader at this moment.
Well, what you tried to do is fundamentally wrong.
When using redux-thunk , you should get something like:

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;
  }
}

If you want to receive the initial data immediately and they are static, then write them to the application page template in window._data and take them through the reducer :
export default (state = window._data) => state;

V
Vitaly, 2018-01-31
@vshvydky

Some kind of left reducer, they don't do that. All requests to the action, when the result is an asynchronous dispatcher of 3 states, the request is started, the request was successful or failed, the Internet is full of ready-made examples of this, google.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question