or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-tanstack--react-query

Hooks for managing, caching and syncing asynchronous and remote data in React

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tanstack/react-query@5.87.x

To install, run

npx @tessl/cli install tessl/npm-tanstack--react-query@5.87.0

0

# @tanstack/react-query

1

2

**Hooks for managing, caching and syncing asynchronous and remote data in React**

3

4

## Package Information

5

6

- **Package:** `@tanstack/react-query`

7

- **Version:** 5.87.1

8

- **License:** MIT

9

- **Documentation:** https://tanstack.com/query

10

- **Repository:** https://github.com/tanstack/query

11

12

TanStack React Query is a comprehensive React hooks library for managing asynchronous state and remote data fetching. It provides powerful caching and synchronization capabilities with automatic refetching strategies, parallel and dependent queries, mutations with reactive query refetching, multi-layer caching with automatic garbage collection, and advanced features like infinite scroll queries, request cancellation, and React Suspense integration.

13

14

## Core Imports

15

16

```typescript { .api }

17

// Essential hooks for data fetching

18

import {

19

useQuery,

20

useInfiniteQuery,

21

useMutation,

22

useQueries

23

} from '@tanstack/react-query'

24

25

// Provider and context

26

import {

27

QueryClient,

28

QueryClientProvider,

29

QueryClientContext,

30

useQueryClient

31

} from '@tanstack/react-query'

32

33

// Suspense-enabled hooks

34

import {

35

useSuspenseQuery,

36

useSuspenseInfiniteQuery,

37

useSuspenseQueries

38

} from '@tanstack/react-query'

39

40

// Utility hooks and state management

41

import {

42

useIsFetching,

43

useIsMutating,

44

useMutationState,

45

useQueryErrorResetBoundary,

46

useIsRestoring,

47

usePrefetchQuery,

48

usePrefetchInfiniteQuery

49

} from '@tanstack/react-query'

50

51

// Configuration helpers

52

import {

53

queryOptions,

54

infiniteQueryOptions,

55

mutationOptions

56

} from '@tanstack/react-query'

57

58

// Components and providers

59

import {

60

HydrationBoundary,

61

QueryErrorResetBoundary,

62

IsRestoringProvider

63

} from '@tanstack/react-query'

64

65

// Core utility functions

66

import {

67

hashKey,

68

matchQuery,

69

matchMutation,

70

keepPreviousData,

71

skipToken,

72

CancelledError,

73

isCancelledError

74

} from '@tanstack/react-query'

75

76

// Core management classes

77

import {

78

QueryCache,

79

MutationCache,

80

QueryObserver,

81

InfiniteQueryObserver,

82

MutationObserver,

83

QueriesObserver

84

} from '@tanstack/react-query'

85

86

// Manager singletons

87

import {

88

focusManager,

89

onlineManager,

90

notifyManager

91

} from '@tanstack/react-query'

92

93

// Hydration utilities

94

import {

95

dehydrate,

96

hydrate,

97

defaultShouldDehydrateQuery,

98

defaultShouldDehydrateMutation

99

} from '@tanstack/react-query'

100

101

// Core data classes

102

import {

103

Query,

104

Mutation

105

} from '@tanstack/react-query'

106

```

107

108

## Basic Usage

109

110

### Setting Up the Provider

111

112

```typescript { .api }

113

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

114

115

// Create a client

116

const queryClient = new QueryClient()

117

118

function App() {

119

return (

120

<QueryClientProvider client={queryClient}>

121

{/* Your app components */}

122

</QueryClientProvider>

123

)

124

}

125

```

126

127

### Basic Query

128

129

```typescript { .api }

130

import { useQuery } from '@tanstack/react-query'

131

132

interface User {

133

id: number

134

name: string

135

email: string

136

}

137

138

function UserProfile({ userId }: { userId: number }) {

139

const {

140

data: user,

141

isLoading,

142

error

143

} = useQuery<User>({

144

queryKey: ['user', userId],

145

queryFn: async () => {

146

const response = await fetch(`/api/users/${userId}`)

147

if (!response.ok) {

148

throw new Error('Failed to fetch user')

149

}

150

return response.json()

151

}

152

})

153

154

if (isLoading) return <div>Loading...</div>

155

if (error) return <div>Error: {error.message}</div>

156

if (!user) return null

157

158

return (

159

<div>

160

<h1>{user.name}</h1>

161

<p>{user.email}</p>

162

</div>

163

)

164

}

165

```

166

167

### Basic Mutation

168

169

```typescript { .api }

170

import { useMutation, useQueryClient } from '@tanstack/react-query'

171

172

interface CreateUserRequest {

173

name: string

174

email: string

175

}

176

177

function CreateUserForm() {

178

const queryClient = useQueryClient()

179

180

const mutation = useMutation({

181

mutationFn: async (newUser: CreateUserRequest) => {

182

const response = await fetch('/api/users', {

183

method: 'POST',

184

headers: { 'Content-Type': 'application/json' },

185

body: JSON.stringify(newUser)

186

})

187

return response.json()

188

},

189

onSuccess: () => {

190

// Invalidate and refetch user queries

191

queryClient.invalidateQueries({ queryKey: ['users'] })

192

}

193

})

194

195

const handleSubmit = (event: React.FormEvent) => {

196

event.preventDefault()

197

const formData = new FormData(event.target as HTMLFormElement)

198

mutation.mutate({

199

name: formData.get('name') as string,

200

email: formData.get('email') as string

201

})

202

}

203

204

return (

205

<form onSubmit={handleSubmit}>

206

<input name="name" placeholder="Name" required />

207

<input name="email" type="email" placeholder="Email" required />

208

<button type="submit" disabled={mutation.isPending}>

209

{mutation.isPending ? 'Creating...' : 'Create User'}

210

</button>

211

{mutation.error && (

212

<div>Error: {mutation.error.message}</div>

213

)}

214

</form>

215

)

216

}

217

```

218

219

### Infinite Query for Pagination

220

221

```typescript { .api }

222

import { useInfiniteQuery } from '@tanstack/react-query'

223

224

interface UsersPage {

225

users: User[]

226

nextCursor?: number

227

}

228

229

function UsersList() {

230

const {

231

data,

232

fetchNextPage,

233

hasNextPage,

234

isFetchingNextPage,

235

isLoading

236

} = useInfiniteQuery<UsersPage>({

237

queryKey: ['users'],

238

queryFn: async ({ pageParam = 0 }) => {

239

const response = await fetch(`/api/users?cursor=${pageParam}`)

240

return response.json()

241

},

242

initialPageParam: 0,

243

getNextPageParam: (lastPage) => lastPage.nextCursor

244

})

245

246

if (isLoading) return <div>Loading...</div>

247

248

return (

249

<div>

250

{data?.pages.map((page, i) => (

251

<div key={i}>

252

{page.users.map((user) => (

253

<div key={user.id}>{user.name}</div>

254

))}

255

</div>

256

))}

257

<button

258

onClick={() => fetchNextPage()}

259

disabled={!hasNextPage || isFetchingNextPage}

260

>

261

{isFetchingNextPage

262

? 'Loading more...'

263

: hasNextPage

264

? 'Load More'

265

: 'Nothing more to load'}

266

</button>

267

</div>

268

)

269

}

270

```

271

272

## API Documentation

273

274

This package provides an extensive API with 74+ distinct functions, hooks, and components. The documentation is organized into focused sections:

275

276

### [Core Query Hooks](./core-query-hooks.md)

277

The foundation of data fetching with caching, background updates, and error handling:

278

- **`useQuery`** - Primary hook for fetching and caching data

279

- **`useInfiniteQuery`** - Hook for paginated/infinite scroll data

280

- **`useQueries`** - Hook for parallel query execution

281

282

### [Suspense Integration](./suspense-integration.md)

283

React Suspense-compatible versions of query hooks:

284

- **`useSuspenseQuery`** - Suspense-enabled data fetching

285

- **`useSuspenseInfiniteQuery`** - Suspense-enabled infinite queries

286

- **`useSuspenseQueries`** - Suspense-enabled parallel queries

287

288

### [Mutations](./mutations.md)

289

Hooks for data modification with optimistic updates and error handling:

290

- **`useMutation`** - Hook for creating, updating, or deleting data

291

- **`useMutationState`** - Hook for accessing mutation state across components

292

- **`useIsMutating`** - Hook for tracking pending mutations

293

294

### [Provider & Context System](./providers-context.md)

295

Components and hooks for managing the QueryClient context:

296

- **`QueryClientProvider`** - Provider component for QueryClient context

297

- **`useQueryClient`** - Hook to access the current QueryClient

298

- **`HydrationBoundary`** - Component for SSR hydration

299

- **`QueryErrorResetBoundary`** - Component for error boundary functionality

300

301

### [Utility Hooks & Functions](./utilities.md)

302

Helper hooks and utilities for advanced query management:

303

- **`useIsFetching`** - Track number of queries currently fetching

304

- **`useIsRestoring`** - Check if queries are being restored from server state

305

- **`usePrefetchQuery`** - Prefetch queries before they're needed

306

- **`usePrefetchInfiniteQuery`** - Prefetch infinite queries

307

308

### [Configuration & Options](./configuration.md)

309

Type-safe configuration helpers and option builders:

310

- **`queryOptions`** - Helper for creating type-safe query configurations

311

- **`infiniteQueryOptions`** - Helper for infinite query configurations

312

- **`mutationOptions`** - Helper for mutation configurations

313

314

## Key Features

315

316

### Automatic Caching & Background Updates

317

```typescript { .api }

318

const { data } = useQuery({

319

queryKey: ['posts'],

320

queryFn: fetchPosts,

321

staleTime: 5 * 60 * 1000, // 5 minutes

322

gcTime: 10 * 60 * 1000, // 10 minutes

323

refetchOnWindowFocus: true,

324

refetchOnReconnect: true

325

})

326

```

327

328

### Optimistic Updates

329

```typescript { .api }

330

const mutation = useMutation({

331

mutationFn: updatePost,

332

onMutate: async (newPost) => {

333

// Cancel outgoing refetches

334

await queryClient.cancelQueries({ queryKey: ['posts'] })

335

336

// Snapshot previous value

337

const previousPosts = queryClient.getQueryData(['posts'])

338

339

// Optimistically update

340

queryClient.setQueryData(['posts'], (old) => [...old, newPost])

341

342

return { previousPosts }

343

},

344

onError: (err, newPost, context) => {

345

// Rollback on error

346

queryClient.setQueryData(['posts'], context.previousPosts)

347

},

348

onSettled: () => {

349

// Always refetch after error or success

350

queryClient.invalidateQueries({ queryKey: ['posts'] })

351

}

352

})

353

```

354

355

### Parallel Queries

356

```typescript { .api }

357

const results = useQueries({

358

queries: [

359

{ queryKey: ['users'], queryFn: fetchUsers },

360

{ queryKey: ['posts'], queryFn: fetchPosts },

361

{ queryKey: ['comments'], queryFn: fetchComments }

362

],

363

combine: (results) => ({

364

data: results.map(result => result.data),

365

pending: results.some(result => result.isPending)

366

})

367

})

368

```

369

370

### Dependent Queries

371

```typescript { .api }

372

const { data: user } = useQuery({

373

queryKey: ['user', userId],

374

queryFn: () => fetchUser(userId)

375

})

376

377

const { data: posts } = useQuery({

378

queryKey: ['posts', user?.id],

379

queryFn: () => fetchUserPosts(user.id),

380

enabled: !!user?.id // Only run when user is loaded

381

})

382

```

383

384

## TypeScript Support

385

386

The package is built with TypeScript and provides comprehensive type safety:

387

388

```typescript { .api }

389

// Generic type parameters for complete type safety

390

const { data } = useQuery<

391

PostsResponse, // TQueryFnData - what the query function returns

392

Error, // TError - error type

393

Post[], // TData - final transformed data type

394

['posts', string] // TQueryKey - query key tuple type

395

>({

396

queryKey: ['posts', filter],

397

queryFn: async ({ queryKey }) => {

398

const [, filterValue] = queryKey // Fully typed query key access

399

return fetchPosts(filterValue)

400

},

401

select: (data) => data.posts // Transform response to Post[]

402

})

403

```

404

405

## Error Handling

406

407

```typescript { .api }

408

const { data, error, isError } = useQuery({

409

queryKey: ['posts'],

410

queryFn: fetchPosts,

411

throwOnError: false, // Handle errors in component instead of error boundary

412

retry: (failureCount, error) => {

413

// Custom retry logic

414

if (error.status === 404) return false

415

return failureCount < 3

416

}

417

})

418

419

if (isError) {

420

return <div>Error: {error.message}</div>

421

}

422

```

423

424

## Server-Side Rendering (SSR)

425

426

```typescript { .api }

427

// Server-side

428

import { QueryClient, dehydrate } from '@tanstack/react-query'

429

430

const queryClient = new QueryClient()

431

await queryClient.prefetchQuery({

432

queryKey: ['posts'],

433

queryFn: fetchPosts

434

})

435

436

// Pass dehydrated state to client

437

const dehydratedState = dehydrate(queryClient)

438

439

// Client-side

440

function App({ dehydratedState }) {

441

const queryClient = new QueryClient()

442

443

return (

444

<QueryClientProvider client={queryClient}>

445

<HydrationBoundary state={dehydratedState}>

446

<Posts />

447

</HydrationBoundary>

448

</QueryClientProvider>

449

)

450

}

451

```

452

453

## Performance & Best Practices

454

455

### Query Key Management

456

```typescript { .api }

457

// Use query key factories for consistency

458

const postKeys = {

459

all: ['posts'] as const,

460

lists: () => [...postKeys.all, 'list'] as const,

461

list: (filters: string) => [...postKeys.lists(), { filters }] as const,

462

details: () => [...postKeys.all, 'detail'] as const,

463

detail: (id: number) => [...postKeys.details(), id] as const

464

}

465

466

// Usage

467

const { data } = useQuery({

468

queryKey: postKeys.detail(postId),

469

queryFn: () => fetchPost(postId)

470

})

471

```

472

473

### Request Deduplication

474

Multiple components calling the same query simultaneously will share the same network request automatically.

475

476

### Garbage Collection

477

Unused query data is automatically garbage collected based on `gcTime` (default 5 minutes).

478

479

### Background Updates

480

Queries automatically refetch in the background when:

481

- Window regains focus

482

- Network reconnects

483

- Query becomes stale

484

- Manual invalidation occurs

485

486

This documentation provides comprehensive coverage of TanStack React Query's capabilities for building robust, performant React applications with powerful data fetching and state management.