1

I am new to redux. So after reading lots of tutorials.I understood that, redux need redux thunk to dispatch async actions by returning another function.But if I call http request inside custom middle-ware then

  1. is it required redux thunk ?
  2. is Redux custom middleware no side effects ? I mean no need to return another function.

If i use redux thunk then my action creator looks like this. This I understood

function incrementAsync() {
  return (dispatch) => {
    setTimeout(() => {
      // Yay! Can invoke sync or async actions with `dispatch`
      dispatch(increment());
    }, 1000);
  };
}

I have confusion in custom middle-ware.

https://blog.logrocket.com/managing-asynchronous-actions-in-redux-1bc7d28a00c6/

as per this blog

const httpMiddleware = store => next => action => {
  if (action[HTTP_ACTION]) {
    const actionInfo = action[HTTP_ACTION];
    const fetchOptions = {
      method: actionInfo.verb,
      headers: actionInfo.headers,
      body: actionInfo.payload || null
    };

    next({
      type: actionInfo.type + "_REQUESTED"
    });

    fetch(actionInfo.endpoint, fetchOptions)
      .then(response => response.json())
      .then(data => next({
        type: actionInfo.type + "_RECEIVED",
        payload: data
      }))
      .catch(error => next({
        type: actionInfo.type + "_FAILED",
        payload: error
     }));
  } else {
    return next(action);
  }
}

they are not returning any dispatch function inside action. I know that store,next,action are the inner functions.

can any one help me to understand about this?
Thank you.

2 Answers 2

3

All redux-thunk is is a simple redux middleware that checks if your action is a function and acts accordingly. You can build it yourself in 5 minutes.

You can see that it deconstructs dispatch and getState from the store object, and then calls your action with them as parameters.

Have a look at it's source code.

So, your example code can look like this:

const httpMiddleware = store => next => action => {
  if (action[HTTP_ACTION]) {
    const actionInfo = action[HTTP_ACTION];
    const fetchOptions = {
      method: actionInfo.verb,
      headers: actionInfo.headers,
      body: actionInfo.payload || null
    };

    store.dispatch({
      type: actionInfo.type + "_REQUESTED"
    });

    fetch(actionInfo.endpoint, fetchOptions)
      .then(response => response.json())
      .then(data => store.dispatch({
        type: actionInfo.type + "_RECEIVED",
        payload: data
      }))
      .catch(error => store.dispatch({
        type: actionInfo.type + "_FAILED",
        payload: error
     }));
  } else {
    return next(action);
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

@Sagi.Thanks for answer. Even i saw that source code..if i call axios or fetch in custom middleware can i direclty dispatch action there itself nstead of next(actonType)
also if i use custom middleware then no needof using redux thunk.am i correct ?
Yes, you are correct. Have a look at the example code that I editted inside the answer.
@sagi.Thank you for clarification.So its clear that custom middleware not require redux thunk.Thanks a lot
2

As you asked by point list I'm gonna reply by point list:

  • If i call http request inside custom middleware then is it required redux thunk ?

Redux thunk is a middleware per se, it's recommended if you want to dispatch an action that make (let's say, for example) an AJAX call and dispatch two different action based on the result of that AJAX call, one if it fails and one if it succeeds.

  • is Redux custom middleware no side effects ? i mean no need to return another function.

If I'm understanding correctly: A middleware will simply take the action you dispatched and pass it through the chain, it'll let you do something before sending the action to the reducer "phase". What it'll do is entirely up to you. You need at least to do next(action) or block the action based on some logic, if needed.

Finally, a custom middleware like the one you posted is modifying the action you passed based on the response of an AJAX call, making it more of an "interceptor" than a simple middleware. Written this way, it's not dispatching a new action, it's more related to modifying the action you passed.

If you want to dispatch a new action based on the result of an ajax call, but without creating a middleware/interceptor, you could do it this way:

const postSomethingAction = postObject => {
    return async dispatch => {
        dispatch(postSomethingPending())
        const response = await Api.postSomething(postObject)
        if (response.message) {
            dispatch(postSomethingError(response))
        }
        else {
            dispatch(postSomethingSuccess(response.data))
        }
    }
}

In this example we're using Thunk do create an action that dispatch another action based on the result of Api.postSomething

3 Comments

@iba.Great.Thanks for posting more insights
in your example i want to call postSomethingAction then i need to dipatch that right .;like dspatch(postSomethingAction (myobject))
Yup, you'll dispatch postSomething which will produce initially a POST_SOMETHING_PENDING action, then based on the result of the ajax call it'll dispatch a POST_SOMETHING_SUCCESS or POST_SOMETHING_FAIL, making it more clear to track the state changes and enabling you to do something until the server responded to your request. It's also a bit less "magic" than doing it in the middleware, but it's much more verbose as you'll need to write something like that for all your action that behaves differently based on your ajax (only if they do)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.