Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions examples/preact/simple/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
15 changes: 15 additions & 0 deletions examples/preact/simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# `create-preact`

<h2 align="center">
<img height="256" width="256" src="./src/assets/preact.svg">
</h2>

<h3 align="center">Get started using Preact and Vite!</h3>

## Getting Started

- `pnpm dev` - Starts a dev server at http://localhost:5173/

- `pnpm build` - Builds for production, emitting to `dist/`

- `pnpm preview` - Starts a server at http://localhost:4173/ to test production build locally
14 changes: 14 additions & 0 deletions examples/preact/simple/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<title>Vite + Preact</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
23 changes: 23 additions & 0 deletions examples/preact/simple/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@tanstack/preact-query": "workspace:^",
"preact": "^10.26.9"
},
"devDependencies": {
"@preact/preset-vite": "^2.10.2",
"eslint": "^9.36.0",
"eslint-config-preact": "^2.0.0",
"typescript": "^5.9.3",
"vite": "^7.0.4"
},
"eslintConfig": {
"extends": "preact"
}
}
15 changes: 15 additions & 0 deletions examples/preact/simple/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions examples/preact/simple/src/assets/preact.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions examples/preact/simple/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { render } from 'preact'
import {
QueryClient,
QueryClientProvider,
useQuery,
} from '@tanstack/preact-query'

export function App() {
const queryClient = new QueryClient()
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
Comment on lines +8 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Move QueryClient instantiation outside the component.

Creating a new QueryClient inside the component body causes it to be recreated on every render, which defeats the purpose of query caching and can lead to memory leaks. The QueryClient should be instantiated once at the module level or memoized.

🔎 Proposed fix
+const queryClient = new QueryClient()
+
 export function App() {
-  const queryClient = new QueryClient()
   return (
     <QueryClientProvider client={queryClient}>
       <Example />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function App() {
const queryClient = new QueryClient()
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
const queryClient = new QueryClient()
export function App() {
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
🤖 Prompt for AI Agents
In examples/preact/simple/src/index.tsx around lines 8 to 15, the QueryClient is
instantiated inside the App component causing a new client on every render; move
the QueryClient creation to module scope (instantiate it once at top-level) or
memoize it with a stable initializer so the same client is reused across
renders, then pass that single instance into QueryClientProvider.


const Example = () => {
const { isPending, error, data, isFetching } = useQuery({
queryKey: ['repoData'],
queryFn: async () => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
)
return await response.json()
},
Comment on lines +20 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add response status validation.

The fetch call doesn't check response.ok, so non-2xx HTTP responses will still attempt JSON parsing and may not be caught properly as errors. This could lead to confusing error messages or unhandled failures.

🔎 Proposed fix
     queryFn: async () => {
       const response = await fetch(
         'https://api.github.com/repos/TanStack/query',
       )
+      if (!response.ok) {
+        throw new Error(`HTTP error! status: ${response.status}`)
+      }
       return await response.json()
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
queryFn: async () => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
)
return await response.json()
},
queryFn: async () => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
return await response.json()
},
🤖 Prompt for AI Agents
In examples/preact/simple/src/index.tsx around lines 20 to 25, the fetch
response is parsed without validating HTTP status; update the queryFn to check
response.ok before calling response.json(), and if not ok throw an error
containing the response status and statusText (optionally including the response
body text/json) so non-2xx responses are surfaced as errors to the caller.

})

if (isPending) return 'Loading...'

if (error !== null) return 'An error has occurred: ' + error.message

return (
<div>
<h1>{data.full_name}</h1>
<p>{data.description}</p>
<strong>👀 {data.subscribers_count}</strong>{' '}
<strong>✨ {data.stargazers_count}</strong>{' '}
<strong>🍴 {data.forks_count}</strong>
<div>{isFetching ? 'Updating...' : ''}</div>
</div>
)
}

render(<App />, document.getElementById('app'))
82 changes: 82 additions & 0 deletions examples/preact/simple/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color: #222;
background-color: #ffffff;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}

body {
margin: 0;
display: flex;
align-items: center;
min-height: 100vh;
}

#app {
max-width: 1280px;
margin: 0 auto;
text-align: center;
}

img {
margin-bottom: 1.5rem;
}

img:hover {
filter: drop-shadow(0 0 2em #673ab8aa);
}

section {
margin-top: 5rem;
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 1.5rem;
}

.resource {
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
text-align: left;
text-decoration: none;
color: #222;
background-color: #f1f1f1;
border: 1px solid transparent;
}

.resource:hover {
border: 1px solid #000;
box-shadow: 0 25px 50px -12px #673ab888;
}

@media (max-width: 639px) {
#app {
margin: 2rem;
}
section {
margin-top: 5rem;
grid-template-columns: 1fr;
row-gap: 1rem;
}
}

@media (prefers-color-scheme: dark) {
:root {
color: #ccc;
background-color: #1a1a1a;
}
.resource {
color: #ccc;
background-color: #161616;
}
.resource:hover {
border: 1px solid #bbb;
}
}
20 changes: 20 additions & 0 deletions examples/preact/simple/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"noEmit": true,
"allowJs": true,
"checkJs": true,

/* Preact Config */
"jsx": "react-jsx",
"jsxImportSource": "preact",
"skipLibCheck": true,
"paths": {
"react": ["./node_modules/preact/compat/"],
"react-dom": ["./node_modules/preact/compat/"]
}
},
"include": ["node_modules/vite/client.d.ts", "**/*"]
}
7 changes: 7 additions & 0 deletions examples/preact/simple/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite';
import preact from '@preact/preset-vite';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [preact()],
});
68 changes: 68 additions & 0 deletions packages/preact-query/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# @tanstack/react-query

## 5.90.11

### Patch Changes

- Prevent infinite render loops when useSuspenseQueries has duplicate queryKeys ([#9886](https://github.com/TanStack/query/pull/9886))

- Updated dependencies [[`c01b150`](https://github.com/TanStack/query/commit/c01b150e3673e11d6533768529a5e6fe3ebee68c)]:
- @tanstack/[email protected]

## 5.90.10

### Patch Changes

- Updated dependencies [[`8e2e174`](https://github.com/TanStack/query/commit/8e2e174e9fd2e7b94cd232041e49c9d014d74e26), [`eb559a6`](https://github.com/TanStack/query/commit/eb559a66dc0d77dd46435f624fa64fc068bef9ae)]:
- @tanstack/[email protected]

## 5.90.9

### Patch Changes

- Updated dependencies [[`08b211f`](https://github.com/TanStack/query/commit/08b211f8aa475e05d2f13a36517fc556861ef962)]:
- @tanstack/[email protected]

## 5.90.8

### Patch Changes

- Updated dependencies [[`c0ec9fe`](https://github.com/TanStack/query/commit/c0ec9fe0d1426fe3f233adda3ebf23989ffaa110)]:
- @tanstack/[email protected]

## 5.90.7

### Patch Changes

- Updated dependencies [[`b4cd121`](https://github.com/TanStack/query/commit/b4cd121a39d07cefaa3a3411136d342cc54ce8fb)]:
- @tanstack/[email protected]

## 5.90.6

### Patch Changes

- Updated dependencies [[`1638c02`](https://github.com/TanStack/query/commit/1638c028df55648995d04431179904371a189772)]:
- @tanstack/[email protected]

## 5.90.5

### Patch Changes

- Updated dependencies [[`e42ddfe`](https://github.com/TanStack/query/commit/e42ddfe919f34f847ca101aeef162c69845f9a1e)]:
- @tanstack/[email protected]

## 5.90.4

### Patch Changes

- Updated dependencies [[`20ef922`](https://github.com/TanStack/query/commit/20ef922a0a7c3aee00150bf69123c338b0922922)]:
- @tanstack/[email protected]

## 5.90.3

### Patch Changes

- Avoid unhandled promise rejection errors during de/rehydration of pending queries. ([#9752](https://github.com/TanStack/query/pull/9752))

- Updated dependencies [[`4e1c433`](https://github.com/TanStack/query/commit/4e1c4338a72f7384600bbda99e44bc1891695df4)]:
- @tanstack/[email protected]
48 changes: 48 additions & 0 deletions packages/preact-query/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<img src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />

![TanStack Query Header](https://github.com/TanStack/query/raw/main/media/repo-header.png)

Hooks for fetching, caching and updating asynchronous data in React

<a href="https://twitter.com/intent/tweet?button_hashtag=TanStack" target="\_parent">
<img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack">
</a><a href="https://discord.com/invite/WrRKjPJ" target="\_parent">
<img alt="" src="https://img.shields.io/badge/Discord-TanStack-%235865F2" />
</a><a href="https://github.com/TanStack/query/actions?query=workflow%3A%22react-query+tests%22">
<img src="https://github.com/TanStack/query/workflows/react-query%20tests/badge.svg" />
</a><a href="https://www.npmjs.com/package/@tanstack/query-core" target="\_parent">
<img alt="" src="https://img.shields.io/npm/dm/@tanstack/query-core.svg" />
</a><a href="https://bundlejs.com/?q=%40tanstack%2Freact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=" target="\_parent">
<img alt="" src="https://deno.bundlejs.com/?q=@tanstack/react-query&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" />
</a><a href="#badge">
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
</a><a href="https://github.com/TanStack/query/discussions">
<img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
</a><a href="https://bestofjs.org/projects/tanstack-query"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Fquery%26since=daily" /></a><a href="https://github.com/TanStack/query/" target="\_parent">
<img alt="" src="https://img.shields.io/github/stars/TanStack/query.svg?style=social&label=Star" />
</a><a href="https://twitter.com/tannerlinsley" target="\_parent">
<img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow" />
</a> <a href="https://gitpod.io/from-referrer/">
<img src="https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod" alt="Gitpod Ready-to-Code"/>
</a>

Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [TanStack Table](https://github.com/TanStack/table), [TanStack Router](https://github.com/tanstack/router), [TanStack Virtual](https://github.com/tanstack/virtual), [React Charts](https://github.com/TanStack/react-charts), [React Ranger](https://github.com/TanStack/ranger)

## Visit [tanstack.com/query](https://tanstack.com/query) for docs, guides, API and more!

## Quick Features

- Transport/protocol/backend agnostic data fetching (REST, GraphQL, promises, whatever!)
- Auto Caching + Refetching (stale-while-revalidate, Window Refocus, Polling/Realtime)
- Parallel + Dependent Queries
- Mutations + Reactive Query Refetching
- Multi-layer Cache + Automatic Garbage Collection
- Paginated + Cursor-based Queries
- Load-More + Infinite Scroll Queries w/ Scroll Recovery
- Request Cancellation
- [React Suspense](https://react.dev/reference/react/Suspense) + Fetch-As-You-Render Query Prefetching
- Dedicated Devtools

### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)

<!-- Use the force, Luke -->
Loading