Skip to content

Commit

Permalink
feat: use queryFnArgs in getQueryData, setQueryData
Browse files Browse the repository at this point in the history
  • Loading branch information
iamchanii committed Nov 22, 2021
1 parent 1515fd4 commit ba9313c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 90 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-frogs-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'react-query-helper': patch
---

Use queryFnArgs in getQueryData, setQueryData and remove undefined args filter logic
93 changes: 23 additions & 70 deletions src/QueryHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ const getPosts = new QueryHelper(
(payload?: { after?: string; first?: number }) => [] as Post[]
);

const getPostById = new QueryHelper(
['post'],
(id?: number) => ({ id, title: `Post#${id}` } as Post)
);

it('should throw error if QueryHelper.setQueryClient not have been called', () => {
// NOTE: Is this right method?
QueryHelper.setQueryClient(null as any);
Expand All @@ -46,17 +51,15 @@ it('should throw error if QueryHelper.setQueryClient not have been called', () =
});

describe('getQueryData', () => {
beforeEach(() => {
it('should get access query data', () => {
queryClient.setQueryData(
['posts'],
[
{ id: 1, title: 'foo' },
{ id: 2, title: 'bar' },
]
);
});

it('should get posts query data', () => {
expect(getPosts.getQueryData()).toMatchInlineSnapshot(`
Array [
Object {
Expand All @@ -70,18 +73,29 @@ describe('getQueryData', () => {
]
`);
});

it('should get access query data with parameter', () => {
queryClient.setQueryData(['post', 1], { id: 1, title: 'foo' });

expect(getPostById.getQueryData(1)).toMatchInlineSnapshot(`
Object {
"id": 1,
"title": "foo",
}
`);
});
});

describe('setQueryData', () => {
it('should set posts query data', () => {
expect(getPosts.getQueryData()).toMatchInlineSnapshot(`undefined`);

getPosts.setQueryData([
getPosts.setQueryData(undefined, [
{ id: 1, title: 'foo' },
{ id: 2, title: 'bar' },
]);

expect(getPosts.getQueryData()).toMatchInlineSnapshot(`
expect(getPosts.getQueryData(undefined)).toMatchInlineSnapshot(`
Array [
Object {
"id": 1,
Expand All @@ -96,9 +110,9 @@ describe('setQueryData', () => {
});

it('should set posts query data as function', () => {
getPosts.setQueryData([{ id: 1, title: 'foo' }]);
getPosts.setQueryData(undefined, [{ id: 1, title: 'foo' }]);

expect(getPosts.getQueryData()).toMatchInlineSnapshot(`
expect(getPosts.getQueryData(undefined)).toMatchInlineSnapshot(`
Array [
Object {
"id": 1,
Expand All @@ -107,15 +121,15 @@ describe('setQueryData', () => {
]
`);

getPosts.setQueryData((oldData) => {
getPosts.setQueryData(undefined, (oldData) => {
if (!oldData) {
return [];
}

return [...oldData, { id: 2, title: 'bar' }, { id: 3, title: 'baz' }];
});

expect(getPosts.getQueryData()).toMatchInlineSnapshot(`
expect(getPosts.getQueryData(undefined)).toMatchInlineSnapshot(`
Array [
Object {
"id": 1,
Expand All @@ -134,11 +148,6 @@ describe('setQueryData', () => {
});
});

const getPostById = new QueryHelper(
['post'],
(id?: number) => ({ id, title: `Post#${id}` } as Post)
);

describe('useQuery', () => {
it('should call useQuery with queryKey based on argument', () => {
const useGetPostById = getPostById.createQuery();
Expand All @@ -157,33 +166,6 @@ describe('useQuery', () => {
`);
});

it('should use only baseQueryKey if argument is not defined or undefined', () => {
const useGetPostById = getPostById.createQuery();
useGetPostById();
useGetPostById(undefined);

expect((useQuery as jest.Mock).mock.calls[0]).toMatchInlineSnapshot(`
Array [
Object {
"queryFn": [Function],
"queryKey": Array [
"post",
],
},
]
`);
expect((useQuery as jest.Mock).mock.calls[1]).toMatchInlineSnapshot(`
Array [
Object {
"queryFn": [Function],
"queryKey": Array [
"post",
],
},
]
`);
});

it('should call useQuery with options from last argument', () => {
const useGetPostById = getPostById.createQuery();
useGetPostById(2, { enabled: true, suspense: true });
Expand Down Expand Up @@ -247,35 +229,6 @@ describe('useInfiniteQuery', () => {
`);
});

it('should use only baseQueryKey if argument is not defined or undefined', () => {
const useGetPosts = getPosts.createInfiniteQuery();
useGetPosts();
useGetPosts(undefined);

expect((useInfiniteQuery as jest.Mock).mock.calls[0])
.toMatchInlineSnapshot(`
Array [
Object {
"queryFn": [Function],
"queryKey": Array [
"posts",
],
},
]
`);
expect((useInfiniteQuery as jest.Mock).mock.calls[1])
.toMatchInlineSnapshot(`
Array [
Object {
"queryFn": [Function],
"queryKey": Array [
"posts",
],
},
]
`);
});

it('should call useInfiniteQuery with options from last argument', () => {
const useGetPosts = getPosts.createInfiniteQuery();
useGetPosts({ after: '', first: 10 }, { enabled: true, suspense: true });
Expand Down
57 changes: 37 additions & 20 deletions src/QueryHelper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {
QueryClient,
UseQueryOptions,
UseInfiniteQueryOptions,
UseQueryOptions,
} from 'react-query';
import { useQuery, useInfiniteQuery } from 'react-query';
import { useInfiniteQuery, useQuery } from 'react-query';
import { QueryFilters } from 'react-query/types/core/utils';

type Awaited<T> = T extends Promise<infer U> ? U : T;
Expand Down Expand Up @@ -33,6 +33,19 @@ export class QueryHelper<
private baseQueryKey: unknown[];
private queryFn: TQueryFn;

private splitArgs<TRestArgs extends unknown[]>(
args: unknown[]
): [TQueryFnArgs, TRestArgs] {
const queryFnArgs = args.slice(0, this.queryFn.length) as TQueryFnArgs;
const restArgs = args.slice(this.queryFn.length) as TRestArgs;

return [queryFnArgs, restArgs];
}

private getQueryKey(queryFnArgs: TQueryFnArgs) {
return [...this.baseQueryKey, ...queryFnArgs];
}

constructor(baseQueryKey: unknown[], queryFn: TQueryFn) {
this.baseQueryKey = baseQueryKey;
this.queryFn = queryFn;
Expand All @@ -45,15 +58,11 @@ export class QueryHelper<
options?: UseQueryOptions<TQueryFnResult>
]
) => {
const queryFnArgs = args
.slice(0, this.queryFn.length)
.filter((arg) => arg !== undefined) as TQueryFnArgs;
const options = args.slice(this.queryFn.length)[0] as
| UseQueryOptions<TQueryFnResult>
| undefined;
const [queryFnArgs, [options]] =
this.splitArgs<[UseQueryOptions<TQueryFnResult>]>(args);

return useQuery({
queryKey: [...this.baseQueryKey, ...queryFnArgs],
queryKey: this.getQueryKey(queryFnArgs),
// TODO: how to handle QueryFunctionContext? should it causes breaking changes?
queryFn: () => this.queryFn.apply(null, queryFnArgs) as TQueryFnResult,
...defaultUseQueryOptions,
Expand All @@ -71,15 +80,11 @@ export class QueryHelper<
options?: UseInfiniteQueryOptions<TQueryFnResult>
]
) => {
const queryFnArgs = args
.slice(0, this.queryFn.length)
.filter((arg) => arg !== undefined) as TQueryFnArgs;
const options = args.slice(this.queryFn.length)[0] as
| UseInfiniteQueryOptions<TQueryFnResult>
| undefined;
const [queryFnArgs, [options]] =
this.splitArgs<[UseInfiniteQueryOptions<TQueryFnResult>]>(args);

return useInfiniteQuery({
queryKey: [...this.baseQueryKey, ...queryFnArgs],
queryKey: this.getQueryKey(queryFnArgs),
// TODO: how to handle QueryFunctionContext? should it causes breaking changes?
queryFn: () => this.queryFn.apply(null, queryFnArgs) as TQueryFnResult,
...defaultUseInfiniteQueryOptions,
Expand All @@ -88,13 +93,25 @@ export class QueryHelper<
};
}

getQueryData(filters?: QueryFilters) {
getQueryData(
...args: [...queryFnArgs: TQueryFnArgs, filters?: QueryFilters]
) {
const [queryFnArgs, [filters]] = this.splitArgs<[QueryFilters]>(args);
const queryClient = this.getQueryClient();
return queryClient.getQueryData<TQueryFnResult>(this.baseQueryKey, filters);

return queryClient.getQueryData<TQueryFnResult>(
this.getQueryKey(queryFnArgs),
filters
);
}

setQueryData(updater: Updater<TQueryFnResult>) {
setQueryData(
...args: [...queryFnArgs: TQueryFnArgs, updater: Updater<TQueryFnResult>]
) {
const [queryFnArgs, [updater]] =
this.splitArgs<[Updater<TQueryFnResult>]>(args);
const queryClient = this.getQueryClient();
return queryClient.setQueryData(this.baseQueryKey, updater);

return queryClient.setQueryData(this.getQueryKey(queryFnArgs), updater);
}
}

0 comments on commit ba9313c

Please sign in to comment.