An utility component for @tanstack/react-query that simplifies types and query state narrowing inside [nested] JSX.
npm install switch-query
# or
yarn add switch-querySupported React Query versions are v5 and v4.
Supported React versions: ^19, ^18, ^17, ^16.8.
Basic example:
import{useQuery}from'@tanstack/react-query';import{SwitchQuery}from'switch-query';constExample=functionExample(){constquery=useQuery({queryKey: ['foo'],queryFn: ()=>Promise.resolve({value: 42}),});return(<SwitchQueryquery={query}pending={<div>loading...</div>}success={({ data })=>(<div>
Value is:
{' '}{data.value}</div>)}error={({ refetch })=>(<div><div>An error occurred</div><buttontype="button"onClick={()=>refetch()}>
retry
</button></div>)}/>);};With error prop you can use typed defined error in render:
import{useQuery}from'@tanstack/react-query';import{SwitchQuery}from'switch-query';constExample=functionExample(){// or explicit error typing useQuery<unknown, CustomErrorClass>(...)constquery=useQuery({queryKey: ['foo'],queryFn: ()=>Promise.reject(newError('Test error')),});return(<SwitchQueryquery={query}error={({ error })=>(<div><h2>An error occurred</h2><div>{error.message}</div></div>)}/>);};Using checkIsEmpty prop you can separate empty state from successful state:
import{useState}from'react';import{useQuery}from'@tanstack/react-query';import{SwitchQuery}from'switch-query';constExample=functionExample(){const[search,setSearch]=useState('');constquery=useQuery({queryKey: ['foo',search],queryFn: ()=>Promise.resolve({fruits: (['apple','banana','orange']).filter((fruit)=>fruit.includes(search))}),});return(<div><div><inputvalue={search}onChange={(e)=>setSearch(e.target.value)}/>{query.isFetching&&<span>fetching...</span>}</div><div><SwitchQueryquery={query}checkIsEmpty={(data)=>!Array.isArray(data)||!data.length}pending={<div>Loading</div>}success={({ data })=>(<ul>{data.fruits.map((fruit)=>(<likey={fruit}>{fruit}</li>))}</ul>)}empty={<div>Nothing found</div>}/></div></div>);};query– React Query object returned fromuseQuery.success– Success state render function or node.query.datais defined.pending– Pending state render function or node. Renders whenquery.status === "pending"orquery.isPending === truebut not on everyquery.isFetching === true.error– Error state render function or node.query.erroris defined and not null.checkIsEmpty– Optional function to check that defined data in success state is empty to renderemptyprop.empty– Empty state render function or node. Renders whencheckIsEmptyreturnstrue.query.datais defined (but empty).