Search code examples
reactjsredux

Difference between redux thunk and a promise


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.


Solution

  • First of all:
    redux action is a plain JavaScript 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/