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)
- (-) diy: ignore remounting in React.strictMode
- (-) diy: isLoading
- (-) diy: isError
- useFetch (use-fetch)
- (+) loading state
- (+) separate result and error states
- (+) reusable
- useSWR (swr)
- (+) 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)
- (+) 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)
- 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]
- 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
Top comments (0)