Fetching data from an api using React/Redux

Markus Claus on March 05, 2019

Starting simple This is my first post here. I decided to share some of the knowledge I earned through making every mistake you can pos... [Read Full]
markdown guide
 

Hi, great post! Instead of using your shouldComponentRender() function, have you considered using componentWillRecieveProps then setting the pending 'state' on this.state similar to this:

  componentWillReceiveProps(nextProps) {
    this.setState({ 
      requestSuccessful: nextProps.success, 
      requestPending: nextProps.pending, 
      requestFailed: nextProps.error });
  }

Then instead of this:

if(!this.shouldComponentRender()) return <LoadingSpinner />

you could use:

if(this.state.requestPending) return <LoadingSpinner />

I think it looks neater and allows you to do something based on state, rather than basing it on whether or not a function was called.
Let me know your thoughts! :)

 

Thank you very much for the comment Calum. :)

I did it a long time like you described and the solution was great. Then componentWillRecieveProps was marked as UNSAFE_componentWillReceiveProps in React 16.3. It will become deprecated in React 17 and the new getDerivedStateFromProps is here.

So I was wondering how I would solve this without depending to much on changes within the React lifecycle methodes and came up with my solution for the problem.

Putting the code into a function that sounded like a lifecycle method was my approach to keep the code readable and make everyone understand what is happening even if the code gets complicated. I keept it that way. :D

Also, I never got the idea why you would put state from redux into the react state if there is no reason to. I mean, you copy data from one state to another without doing anything with it. Seems like a waste of time. Can you enlighten me? Is there any benefit?

 

Even better :

let { requestPending } = this.state;

{ requestPending && <LoadingSpinner /> }
 

Nice post. One question. You do this:

import fetchProductsAction from 'fetchProducts';

but i don't see fetchProductsAction in fetchProducts.js. I see only fetchProducts. Is this a typo or some code is missing?. I believe is only a mistake but just want to confirm.

Thanks.

 

Thank you for the reply Alejandro.

You can import default exports with whatever name you want. I wanted to use fetchProducts in my code so I can't import it with this name because it would collide with the variable I use in a deeper scope.

To fix this I import everything that is a action with xxxAction and then use it without the Action suffix.

I hope this clarifies things.

 

You're right. I got confused. I'm learning react so i'm kind of new in those details and scanning the code properly.

Thanks!

You are welcome mate. Good luck learning :)

 

Hey Markus! Congrats on your first blog post! Shameless plug, I built a middleware a while ago to help reduce boilerplate especially with async actions like the ones you mentioned in this article, you should check it out!

github.com/Gabri3l/redux-slim-async

 

Hey Gabriele,

thanks for the tip. I know middlewares like yours. I used another one in a project recently. Was a real timesaver.

I will checkout yours for sure.

 

Recommend? Not really. I used redux-promise and redux-action to achieve something like your middleware does.

In small applications it was great (as I think your middleware will be) but in larger scale applications there were cases where the thunks got complicated and I had to get rid of all the middlewares I found and do it from scratch (or with my own middleware in that case)

That's interesting! I used this for a medium/large codebase and we were fine so if you have a minute to bring up a complicated Case that made those middlewares unhelpful that would be great! I'm curious to see if there's a way I can adapt this one too not intricate use cases.

 

This was a great article, I really appreciate the practical example, too many times it's not so.

One bit of feedback, I noticed in your fetchProducts.js file you have a typo:

dispatch(fetchProductsSuccess(res.products);

you're missing a closing parenthesis at the end of the dispatch

dispatch(fetchProductsSuccess(res.products));

 

Hi Markus,

Let's assume i want to use some value from store and pass it as a parameter to products API call in fetchProducts.js. How can i access that ?? Something like

fetch(https://exampleapi.com/products/${store.someVariable})

how can i access store object in fetchProducts.js ??

 

There a few methods that can help you using state variable in thunk function:

  1. You can export the state. Create a separate .js file and export the state object by using createStore(reducerName) method, then import that state object and use the getState() method to access the store.

  2. You can directly use getState in your app-thunk function by simply passing it as an argument like return (dispatch,getState) => {} and then use this getState() method to access the store.

There are some other methods but these should work.

 

Hey Markus, thanks a lot for your guide. Great post!

 
 

Hello Markus, I'm getting fetchProducts() is not a function in your componentWillMount function. And I don't see where it is defined. ComponentWillMount is being depricated, but don't think that is why i'm getting this error. Thank you
componentWillMount() {
const {fetchProducts} = this.props;
fetchProducts();
}

 
 

Thank you for the article Markus!

redux-thunk is a great library, but not easy to test unfortunately, that’s why we decided to go with redux-saga, IMHO makes the code easier to maintain and the learning curve is not much difficult than thunk if you go to the great official documentation. Have you tried it?

Kudos!

 

Hi Markus,

Thanks for the wonderful explanation.

Could you please explain why do we have to import the constants from ../actions.js in reducer.js?

import {FETCH_PRODUCTS_PENDING, FETCH_PRODUCTS_SUCCESS, FETCH_PRODUCTS_ERROR} from './actions';

 
 

Hi Markus, Nice tutorial can you please share the code.

 

I was stucked with this but thanks to your it's solved. This is the ebst guide ever, even being short.

 

Hello! Is it possible to use a function component instead of a class component for ProductView ? How would the code change with useEffect hook? Thanks!

 

I actually wrote an article about React Hooks not long ago and there is an example for a fetch hook. Check it out

 

This code is subject to race conditions.

Check my post about that subject here: dev.to/sebastienlorber/handling-ap...

 

Is there a book or video describing the use of these react design patterns and/or the use of redux? For beginners maybe?

 

There are literally thousands out there. I can recommend Frontend Masters, they got plenty on all the relevant subjects but they are not free. Also YouTube is full of content. Udemy has some pretty good courses for little money, too.

 

The best article to have a better understanding of redux and usage of APIs with redux. Thanks a bunch.

code of conduct - report abuse