Skip to content

Commit c6c90f9

Browse files
committed
update simple example
1 parent 2cdeb7d commit c6c90f9

File tree

4 files changed

+83
-28
lines changed

4 files changed

+83
-28
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { QueryClient, queryOptions, useMutation, useQuery } from '@tanstack/react-query';
2+
3+
type ArticleData = { id: number; title: string; body: string; userId: number };
4+
5+
const client = new QueryClient();
6+
7+
const articlesQuery = queryOptions<ArticleData[]>({
8+
queryKey: ['articles'],
9+
queryFn: () => fetch('https://api.example.com/articles').then((res) => res.json()),
10+
});
11+
12+
export function App() {
13+
const { isLoading, data } = useQuery(articlesQuery);
14+
15+
return (
16+
<>
17+
{isLoading && <p>Loading...</p>}
18+
19+
{data?.map((article) => (
20+
<ArticleView key={article.id} article={article} />
21+
))}
22+
</>
23+
);
24+
}
25+
26+
function ArticleView({ article }: { article: ArticleData }) {
27+
const { mutateAsync, isPending } = useMutation({
28+
mutationFn: (params: { id: number }) => {
29+
return fetch(`https://api.example.com/articles/${params.id}`, { method: 'DELETE' });
30+
},
31+
onSuccess: () => client.invalidateQueries({ queryKey: articlesQuery.queryKey }),
32+
});
33+
const onDelete = () => mutateAsync({ id: article.id });
34+
35+
return (
36+
<div key={article.id}>
37+
<h2>{article.title}</h2>
38+
<p>{article.body}</p>
39+
40+
<button onClick={onDelete} disabled={isPending}>
41+
Delete
42+
</button>
43+
</div>
44+
);
45+
}

examples/vite/src/examples/simple/example.tsx

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,44 @@ type ArticleData = { id: number; title: string; body: string; userId: number };
55

66
const client = new QueryClient();
77

8-
const builder = new HttpQueryBuilder().withClient(client).withBaseUrl('https://api.example.com').withTagTypes<{
9-
articles: ArticleData[];
10-
refreshable: unknown;
11-
}>();
8+
const builder = new HttpQueryBuilder().withClient(client).withBaseUrl('https://api.example.com');
129

13-
const articlesQuery = builder.withTags('refreshable', 'articles').withPath('/articles').withData<ArticleData[]>();
10+
const articlesQuery = builder //
11+
.withPath('/articles')
12+
.withData<ArticleData[]>()
13+
.withTags('articles');
1414

15-
const deleteArticleMutation = builder.withUpdates('articles').withMethod('delete').withPath('/articles/:id');
15+
const deleteArticleMutation = builder //
16+
.withMethod('delete')
17+
.withPath('/articles/:id')
18+
.withUpdates('articles');
1619

17-
export function MyApp() {
18-
const [refresh, { isPending: isRefreshing }] = builder.tags.useOperation({ tags: 'refreshable' });
19-
const articles = articlesQuery.useQuery({});
20-
const deleteArticle = deleteArticleMutation.useMutation();
21-
22-
const onDelete = (id: number) => deleteArticle.mutateAsync({ params: { id } });
23-
24-
if (!articles.isSuccess) return <>Loading...</>;
20+
export function App() {
21+
const { isLoading, data } = articlesQuery.useQuery({});
2522

2623
return (
2724
<>
28-
<button onClick={() => refresh()} disabled={isRefreshing}>
29-
Refresh all articles
30-
</button>
25+
{isLoading && <p>Loading...</p>}
3126

32-
{articles.data.map((article) => (
33-
<div key={article.id}>
34-
<h2>{article.title}</h2>
35-
<p>{article.body}</p>
36-
37-
<button onClick={() => onDelete(article.id)} disabled={deleteArticle.isPending}>
38-
Delete
39-
</button>
40-
</div>
27+
{data?.map((article) => (
28+
<ArticleView key={article.id} article={article} />
4129
))}
4230
</>
4331
);
4432
}
33+
34+
function ArticleView({ article }: { article: ArticleData }) {
35+
const { mutateAsync, isPending } = deleteArticleMutation.useMutation();
36+
const onDelete = () => mutateAsync({ params: { id: article.id } });
37+
38+
return (
39+
<div key={article.id}>
40+
<h2>{article.title}</h2>
41+
<p>{article.body}</p>
42+
43+
<button disabled={isPending} onClick={onDelete}>
44+
Delete
45+
</button>
46+
</div>
47+
);
48+
}

packages/tanstack-query-builder/src/builder/QueryBuilderFrozen.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export class QueryBuilderFrozen<
179179
//#region Queries
180180

181181
private useQueriesInternal(
182-
useHook: typeof useQueries | typeof useSuspenseQueries,
182+
useQueriesImpl: typeof useQueries | typeof useSuspenseQueries,
183183
...[queries, sharedVars, sharedOpts]: UseQueriesArgs<TVars, TData, TError, TKey>
184184
): BuilderQueriesResult<TVars, TData, TError, TKey> {
185185
assertThis(this);
@@ -192,7 +192,7 @@ export class QueryBuilderFrozen<
192192
this.getQueryOptions(this.mergeVars([sharedVars!, vars as any]), mergeBuilderOptions([sharedOpts, options]), 'queries'),
193193
);
194194

195-
const result = useHook({ queries: queryList }) as ResultType;
195+
const result = useQueriesImpl({ queries: queryList }) as ResultType;
196196

197197
const queryMap: ResultType['queryMap'] = {};
198198
for (let index = 0; index < mapKeys.length; index++) {

website/docs/api/http.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ Various options can be passed to the HTTP client on each request. These options
77

88
## Options
99

10+
The following options can be passed to the HTTP client on each request.
11+
12+
Note that some of these options will not be used in the construction of the query key, meaning that they will not refetch the query when they change.
13+
Options that may change the response will be used in key creation.
14+
These are `method`, `baseUrl`, `path`, `params`, `search`, `headers`, `body`, `responseType` and additionally `key`.
15+
1016
### `method`
1117

1218
The HTTP method to be used for the request. It's `GET` by default and can also be `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`, or `TRACE`.

0 commit comments

Comments
 (0)