React Redux adding extra field for action promises to return differently

I want to add the isLoading flag to my action generator and reset it to my reducer. Initially without a flag, my code works and the action looks like this

export function getList() {
    const FIELD = '/comics'
    let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;
    const request = axios.get(searchUrl)
    return {
        type: FETCH_LIST, 
        payload: request,
    }
}

      

and the reducer looks like

const INITIAL_STATE = { all: [], id: -1, isLoading: false };

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case FETCH_COMIC_LIST: 
            console.log('reducer action =', action, 'state =', state)
            return {
                ...state, 
                all: action.payload.data.data.results,
                isLoading: false
            }
        default:
            return state;
    }
}

      

Good result

As you can see the object is returned ok and I can get my list via action.payload.data.data.results

Please note that I am using redux promise as my promise fulfillment middleware.

As soon as I change my action to the following and run the code, I receive my payload (as shown in the image below) as a promise, not a returned object

export function getComicList() {
    const FIELD = '/comics'
    let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;
    const request = axios.get(searchUrl)
    return {
        type: FETCH_COMIC_LIST, 
        isLoading: true, 
        payload: request,
    }
}

      

isLoading added

Why is it just adding another variable causing this problem?

+3


source to share


3 answers


Redux Promise and Redux Promise Middleware are Flux Standard Action (FSA) compliant . Add a key meta

to the action and assign key / value pairs in it.

Related question / answer: fooobar.com/questions/1628491 / ...



From FSA documentation:

The optional meta property MAY be any value type. It is for any additional information that is not part of the payload.

+2


source


Try this how it is done with redux-thunk, so I hope it looks like redux-prom-middleware. Also see what is returned:

all: action.payload

in your gearbox



    export function getList() {
        const FIELD = '/comics'
        let searchUrl = ROOT_URL + FIELD + '?ts=' + TS + '&apikey=' + PUBLIC_KEY + '&hash=' + HASH;

        // return a promise that the middleware should handle
        // return response or error from promise
        return axios.get(url)
          .then((response) => {
            type: FETCH_LIST,
            isLoading: true, 
            payload: response
          }).error((response) => {
            //handle error
          });
    }

      

-1


source


I think the cleanest and most responsive way is:

//types:
const FETCH_LIST_START = "…";
const FETCH_LIST_SUCCESS = "…";
const FETCH_LIST_ERROR = "…";

//action
const loadList = url => dispatch => {
  dispatch({type: FETCH_LIST_START });

  fetch(url)
    .then(res => {
      if (res.status !== 200) throw new Error('load failed');
      dispatch({ 
        type: FETCH_LIST_SUCCESS,
        payload : { res } }
      })

    )
    .catch(err => dispatch({ 
      type: FETCH_LIST_ERROR, 
      payload: { error } })
    );
};

//REDUCER
case: FETCH_LIST_START:
  return Object.assign({}, state, { isLoading: true });
  break;
case: FETCH_LIST_SUCCESS:
  return Object.assign({}, state, { 
     isLoading: false, 
     data: action.payload.res
  });
  break;
case FETCH_LIST_ERROR:
  break;

      

So, it assumes you are using redux-thunk. The main idea is to make the reducer manage the state, including the setting isLoading

, this way you can update your component while the request state changes ... The code above is not ready for copy / paste, it is meant to carry over the idea.

-1


source







All Articles