The Best Practice on Data Fetching

Learn best practice on data fetching using the Redux toolkit.

We'll cover the following

The modern Redux journey isn’t quite done yet!

Place 5 intermediate or senior frontend engineers in a room, and ask their opinion on the best way to fetch data in a growing frontend application. You’re likely going to end the meeting 3 hours later without reaching a conclusion.

Okay, maybe 3 hours is a little too much, but I won’t be surprised if that happens!

Data fetching is a core part of every decent web application, and there are several ways to go about it.

Redux apps don’t live isolated. In the context of a React application, they live within a React app! This forces you to not only think about “Redux” but take a more holistic approach by considering the entire frontend application.

Older Redux patterns

Middleware adaptations such as Redux-saga and Redux-observable was the best approach to manage the async operations of a growing web application.

I’m not disregarding them as healthy solutions.

However, before you consider adding these to your application today, make sure you understand the downsides and modern alternatives available to you.

Redux toolkit provides thunks by default. Before Redux toolkit, they perhaps seemed like a joke and handled simple async operations, but that’s not quite the case now.

Explore the createAsyncThunk API. It’s rich and abstracts the logic for most async operations.

A subject that hasn’t been discussed in detail yet is canceling API requests using createAsynThunk. Yes, createAsyncThunk supports that! Before RTK, you had to turn to other solutions for this, e.g., Redux-saga or handling cancellation at the AJAX library level, e.g., with Axios.

Here’s what a simple example with createAsyncThunk would look like:

function YourComponent(props: { userId: string }) {
  const dispatch = useAppDispatch()
  React.useEffect(() => {
    // Dispatching the thunk returns a promise
    const promise = dispatch(fetchUserById(props.userId))
    // the useEffect cleanup callback
    return () => {
      // `createAsyncThunk` attaches an `abort()` method to the promise
      promise.abort()
    }
  }, [props.userId])
} 

By calling promise.abort in the useEffect cleanup function, you can effectively abort the request if the component is unmounted.

Thunks can do most things sagas can’t. For example:

  • Thunks are easier to reason about.
  • Thunks do not require creating extra actions to act as “background workers” for sagas to get triggered.
  • Thunks can synchronously execute logic including dispatch() and getState() and can continue to do more work immediately.
  • Thunks can return a value, such as a promise to the site that dispatched them, e.g., in the example above. This can be useful for executing component logic after a fetch has completed.
  • The thunk middleware is way smaller compared to the saga middleware, which is 5.3K min gzipped.

In a nutshell, favour the use of createAsyncThunk.

If you’re worried about complex promise chains, use the async await syntax. If you’re worried about giving up the testability that sagas provide, thunks aren’t that difficult to test. You just have to mock whatever your AJAX library is, e.g., via jest.mock().

The bigger picture

If we leave the Redux bubble for a minute and consider the bigger picture of data fetching in a Redux app (which is, by the way, a React app), then we introduce even more players into the game.

You don’t always have to handle data fetching via Redux. Sometimes there’s a better tool for the job. That’s just the truth!

If your application deals with constantly changing data, and you’d like to handle caching, background updates, prefetching, etc., take a look at react-query. It could really simplify your date fetch and sync logic.

If you want the same (or almost the same) benefits react-query provides but would rather keep your async state in Redux, keep an eye on RTK-query. If it’s successful, it’s likely going to make it to the Redux toolkit library sometime in the future. Check it out.

Like mentioned before, data fetching isn’t a “one answer fits all” subject. I wanted to make sure you were aware of some fine options that you have.

Get hands-on with 1200+ tech skills courses.