Do I need a fetching library in React?
Tags: webdev, react, nextjs, performance
Published: 2022-07-27 10:37:43

## Assumptions

- server state - as a single source of truth
- you want/need CSR

## What does a fetching library do?

- tracking loading and error state (ui spinner or notification/toast on error)
- deduplicate requests (prevent race conditions, minimize requests)
- manage cache (precisely control then to keep or revalidate data)
- automatically re-fetch (on tab switching, network loss, periodically, pc/laptop sleep)

Why do I need deduplication?

- if using React.strictMode (remounts all components twice, -just for fun- to be future proof for upcoming parallel rendering)
- if calling the same API across multiple components
- if opening the app in multiple tabs

Why do I need to manage the cache?

- for fast/faster ui performance
- to reduce server load or completely prevent an unresponsive/overloaded server

Why do I need automatic re-fetching?

- if you experience a network disconnect and reconnect (data on the server may have changed)
- if your pc/laptop goes to sleep and wakes up (a long time may have passed)
- if you leave the tab open and browse elsewhere (again, a long time may have passed)

## How to fetch

- directly using ([fetch/axios](https://beta.reactjs.org/learn/you-might-not-need-an-effect))
  - (-) diy: ignore remounting in React.strictMode
  - (-) diy: isLoading
  - (-) diy: isError
- useFetch ([use-fetch](https://usehooks-ts.com/react-hook/use-fetch))
  - (+) loading state
  - (+) separate result and error states
  - (+) reusable
- useSWR ([swr](https://swr.vercel.app/))
  - (+) built-in (in memory) cache
  - (+) request deduplication - can call same api in multiple components
  - (+) re-fetch/revalidate on focus - then switching windows/tabs
  - (+) re-fetch/revalidate on network recovery - internet loss or then laptop goes to sleep
  - (+) local mutation, optimistic UI updates
- useQuery ([react-query](https://github.com/tannerlinsley/react-query))
  - (+) all from above
  - (+) even more features
  - (-) more complex, even the examples are complex, has more aggressive defaults (re-fetching every 2s)
- Redux Query ([rkt-query](https://redux-toolkit.js.org/rtk-query/overview))
  - skipped / not analyzed, 
   since I already got burned by Redux's verbosity/complexity/overengineering on its introduction

## Web app architecture

A fetching library influences how you structure a web app, it incentivizes you to structure your code in a way, that isn't obvious at first sight.

Web app architectures

- centralized, top-to-bottom
- decentralized, multiple fetch calls from different components

Centralized, top-to-bottom web arch

- parent/root fetches all data and passes it down with prop drilling or react context
- recommended by official React docs [[1](https://beta.reactjs.org/learn/you-might-not-need-an-effect#passing-data-to-the-parent)]
- the most simple approach, works beautifully in small apps
- very easy to reason about and debug
- my recommendation: write a custom API that delivers all needed data in one fetch call, 1 api for each page
- may not be possible in more complex web apps or if some parts need to be refreshed quite often 

Decentralized web arch

- each component fetches its own data
- the only way to structure highly complex web apps
- deduplication is a must-have feature -> a fetching library is required to be used

## Downsides of using a fetching library

- does not work with PWA / offline-first apps
  - local/offline changes may/will be overwritten by fetching old server state
  - may be circumvented / 
    (-> need to write own custom logic -> how?)
- CSR vs SSR: CSR may be more work than SSR.
  - in SSR you just simply directly call the db and pass the ready data to the UI

## (Not-)Alternatives

If applicable (no highly dynamic content)
consider using

- SSR
- Centralized, top-to-bottom web arch

SSR

- is a much simpler approach and
- you do not need to care about fetching or writing APIs at all
- because all the calls happen on the server and you do not need to do extensive validation (or need to do less of it)

Centralized, top-to-bottom web arch

- make custom APIs for each ui page
- to minimize ui api calls and return all needed data at once
- managed by the most parent/container/wrapper

## Side notes

fetching libraries can act or even replace a state manager
how?

- with mutate -> you can trigger change state of others
- if you change url/key -> data will be refetched
- you always get current data from the hook

why?

- if you can reduce the amount of code and/or complexity it is always worth it
  (if it is possible to do, and you do not rely on state-manager features that are crucial to your web app)

## Terminology

- ui - User interface
- db - Database
- offline-first - web app works completely normal without an internet connection
- PWA - Progressive Web Apps
- arch - Architecture
- CSR - Client Side Rendering
- SSR - Server Side Rendering