0

I just started learning about Redux, and I have a question about its purpose. According to what I know, redux-thunk delays the dispatch of an action, so in the code below, it waits until the server response before it dispatches. But isn't it the job of a promise. With my basic knowledge, the call-back inside then should only be called once we get the response anyway, right?

export const fetchRentalById = (rentalId) => {
  return dispatch => {  
    axios.get(`/api/v1/rentals/${rentalId}`)
    .then((rental) => {
      dispatch({
      type: FETCH_BY_ID,
      payload: rental.data
    })
  })
 }
}

So I tried removing the dispatch in return, and for some reasons it will dispatch in before the server response, but it doesn't seem to make sense to me. Thank you for reading. Call in component

const {rental, fetchRentalById} = props;
  let rentalId = props.match.params.id;
  useEffect(() => {
    fetchRentalById(rentalId);
  }, [ rentalId, fetchRentalById]);
...
const mapState = state => {
  return {
    rental: state.data.rental
  };
};
export default connect(mapState, {fetchRentalById})(RentalDetail);

I use mapDispatchToProps, so I don't need to use props.dispatch here.

Free Me
  • 195
  • 2
  • 10
  • Redux doesn't delay the dispatch of the action, that *is* the job of the promise returned by axios.get. It's unclear where you moved the dispatch to, what happened as a result or how you expected moving it to help. – jonrsharpe Dec 28 '19 at 11:39
  • @jonrsharpe yes I made a big mistake. It's redux-thunk that delays a dispatch, if an action returns a dispatch before an async call, like the example above. Sorry for that mistake. – Free Me Dec 28 '19 at 11:48
  • can you add your fetchRentalById call from your component ? – Rami Loiferman Dec 28 '19 at 12:17
  • @RamiLoiferman it's editted. Thank you. – Free Me Dec 28 '19 at 12:34
  • Does this answer your question? [How does middleware execute async actions?](https://stackoverflow.com/questions/59487232/how-does-middleware-execute-async-actions) – Asaf Aviv Dec 28 '19 at 15:23
  • @AsafAviv yes I already knew how thunk works. What I am asking is why we have to wait to dispatch, when promise already waits for the server response. – Free Me Dec 28 '19 at 17:01
  • Because you need to include the data when you dispatch the actual action object so you have to wait for the promise to resolve to access the data – Asaf Aviv Dec 28 '19 at 17:03
  • @AsafAviv so dispatch is in a callback of then, right? If it's a callback, does it mean it will only execute when we have the response anyway? This is exactly what I'm asking, and you are very close. Dispatch will be called once we have the response in then anyway, so why the need to wait for it? – Free Me Dec 28 '19 at 17:09
  • 1
    `redux-thnuk` just inject the `dispatch` function as an argument to your action when your action is a function, it doesn't care if it's sync or async, the only thing it does is it gives you the ability to call dispatch whenever you want from inside the thunk – Asaf Aviv Dec 28 '19 at 17:12

1 Answers1

2

First of all:
redux action is a plain java script object not a function
In your case

const action = {
   type: FETCH_BY_ID,
    payload: rental.data
}

Only this is the action.
And only this is what you allowed to pass to dispatch()

Now the dispatch function comes from your component So without redux-thunk you will have to change

export const fetchRentalById = (rentalId) => {

to

export const fetchRentalById = (dispatch,rentalId) => {

And pass dispatch from component to this function


So in conclusion ----------------

What redux-thunk helps you with?
Just the syntax now you can return a function on your action creator.

how ? Redux tunk intercept all actions and if it is a function it calls it.

But the Promise is still a headache. You can read more [here][1] and [here][2]

If you want specific promise middleware you can choose one of this : From [https://redux.js.org/advanced/async-actions/][3]

Thunk middleware isn't the only way to orchestrate asynchronous actions in Redux:

You can use redux-promise or redux-promise-middleware to dispatch Promises instead of functions. You can use redux-observable to dispatch Observables. You can use the redux-saga middleware to build more complex asynchronous actions. You can use the redux-pack middleware to dispatch promise-based asynchronous actions. You can even write a custom middleware to describe calls to your API, like the real world example does. It is up to you to try a few options, choose a convention you like, and follow it, whether with, or without the middleware.

I'm using redux-promise;

In redux promise your action creator will look like this :

export const fetchRentalById = (rentalId) => {
  return {
    type: FETCH_BY_ID,
   // you can take the .data in other function on in reducer
    payload: axios.get(`/api/v1/rentals/${rentalId}`) 
  }
}

Makes the code much cleaner [1]: Why do we need middleware for async flow in Redux? [2]: https://daveceddia.com/what-is-a-thunk/ [3]: https://redux.js.org/advanced/async-actions/

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
Rami Loiferman
  • 853
  • 1
  • 6
  • 22
  • @FreeMe did it answer your question ? – Rami Loiferman Dec 28 '19 at 16:06
  • Hi, sorry for making you wait. *The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met*. This is from the redux-thunk page. So am I understanding correctly that thunk delays the dispatch action until the server response, and it does that by dispatching a function instead of an action right? And if I do, doesn't promise do the same thing? – Free Me Dec 28 '19 at 17:05
  • https://github.com/reduxjs/redux-thunk/blob/master/src/index.js – Rami Loiferman Dec 28 '19 at 17:35
  • I suggest you to read the code this helped me the most to understand this library, yes what you quoted "The thunk can be used to delay the dispatch of an action" is correct but also confusing . Delay meaning here is that the action will be dispatched inside *your* function and yes *your* function can make a delay – Rami Loiferman Dec 28 '19 at 17:41
  • As can be understood from the example user this quote they show dispatch called inside setTimeout(() function – Rami Loiferman Dec 28 '19 at 17:42
  • the only thing redux-thunk does is check if your action is a function , and if so call it with (dispatch, getState, extraArgument) params – Rami Loiferman Dec 28 '19 at 17:45
  • ok, one final question. How do you know when you need to delay it, and when you can dispatch it directly from your actions.js. Thank you very much. – Free Me Dec 28 '19 at 18:04
  • Can you clarify your last question ? – Rami Loiferman Dec 28 '19 at 18:12
  • Oh no I understand it now. Thank you every much. +1 for your answer. Thank you for your enthusiasm. – Free Me Dec 28 '19 at 18:15
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/204993/discussion-between-free-me-and-rami-loiferman). – Free Me Dec 28 '19 at 18:30