Skip to main content
useResource is Solar’s hook for async data fetching. It manages the full lifecycle: starting the request, tracking loading and error state, and automatically cancelling in-flight requests when the key changes. You get a clean, predictable data-fetching primitive without managing AbortController instances yourself.

Signature

const { data, loading, error } = useResource({ key, fetch })

Parameters

key
any
required
The dependency key for this resource. Solar serializes the key with JSON.stringify and compares it on every render. When the key changes, the previous in-flight request is aborted and a new fetch begins immediately.
fetch
async function
required
An async function with the signature async (signal) => value. Solar passes an AbortSignal as the argument. The function should return the resolved data value; Solar stores it as data on success or captures the thrown error as error on failure.

Returns

data
any
The resolved value from your fetch function, or null while loading or after an error. When the key changes and a re-fetch begins, data retains its previous value until the new request resolves.
loading
boolean
true while a fetch request is in flight. Becomes false once the request resolves or rejects.
error
Error | null
The error caught from a rejected fetch call, or null when the most recent fetch succeeded or is still in flight.

Example: User profile

const UserProfile = defineComponent({
  name: 'UserProfile',
  props: { userId: { type: 'number', required: true } },
  render({ userId }) {
    const { data, loading, error } = useResource({
      key: userId,
      fetch: async (signal) => {
        const res = await fetch(`/api/users/${userId}`, { signal })
        if (!res.ok) throw new Error(`HTTP ${res.status}`)
        return res.json()
      },
    })

    if (loading) return createElement('p', {}, 'Loading...')
    if (error)   return createElement('p', {}, `Error: ${error.message}`)
    return createElement('div', {},
      createElement('h2', {}, data.name),
      createElement('p', {}, data.email),
    )
  },
})

Stale data during re-fetch

When the key changes and a new fetch begins, data keeps its last resolved value rather than resetting to null. You can use this to show the previous content while the new data loads. Check loading to know whether a re-fetch is currently in progress.

Cancellation

Solar creates a new AbortController for every fetch and passes its signal to your fetch function. When the key changes or the component unmounts, Solar calls controller.abort() — which triggers the signal and cancels the request at the network level. Always forward the signal to your underlying fetch call:
fetch: async (signal) => {
  const res = await fetch('/api/data', { signal })
  return res.json()
}
If you don’t pass signal to your fetch call, the network request will not be cancelled when the key changes or the component unmounts. Solar will still ignore the result, but the request itself continues running in the background, consuming bandwidth and server resources.