How to conditionally load data with SWR
By Flavio Copes
Learn how to conditionally load data with SWR by passing null as the key until your data is ready, so the request only fires once you can make it.
To conditionally load data with SWR, pass null as the key instead of the URL. When the key is null, SWR skips the request entirely, and it fires it as soon as the key becomes a real value.
Why do we need this? Because useSWR() is a React hook, and hooks must run on every render. You can’t wrap it in an if statement. So SWR gives us a way to say “don’t fetch yet” through the key itself.
For example, one case I had was, I had to figure out if the user was logged in before sending a request to a /api/user endpoint to get the user’s data.
In particular, I had a session object, and inside it, a user object. Both needed to be defined.
So here’s what I did:
import fetcher from 'lib/fetcher'
//...
const { data: userData } = useSWR(session && session.user ? `/api/user` : null, fetcher)
The first parameter is the key, usually the URL to request. If it’s null, then SWR does not perform the request, and solves the original problem.
What happens when the key changes
While the key is null, both data and error stay undefined. Nothing happens.
The nice part is that this is reactive. When the session loads and the component re-renders, the key switches from null to /api/user, and SWR starts the request automatically. No manual triggering needed.
Dependent requests
The same pattern chains requests that depend on each other. Say you need the user before you can load their orders:
const { data: user } = useSWR('/api/user', fetcher)
const { data: orders } = useSWR(user ? `/api/orders?user=${user.id}` : null, fetcher)
The second request waits until the first one returns. SWR calls this dependent fetching.
Be careful with the undefined data
While the request is paused, data is undefined. That’s the same value you get while a request is loading.
So your component can’t tell “not fetching yet” from “still fetching” by looking at data alone. Guard your rendering:
if (!userData) return <p>Loading...</p>
If you need to distinguish the two states, you already have the condition that built the key. Check session && session.user again: if it’s false, you’re paused, not loading.
Related posts about js: