Skip to content

Commit 0f4c9cc

Browse files
committed
Added auto dispatch to React useQuery
1 parent 733066f commit 0f4c9cc

File tree

5 files changed

+101
-26
lines changed

5 files changed

+101
-26
lines changed

.eslintrc

+3-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292
"react/jsx-no-script-url": 2,
9393
"react/jsx-no-useless-fragment": 2,
9494
"react/jsx-pascal-case": 2,
95-
"react/jsx-filename-extension": 2
95+
"react/jsx-filename-extension": 2,
96+
97+
"react-hooks/exhaustive-deps": 0
9698
}
9799
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
1+
import { useEffect, useCallback } from 'react';
12
import { useSelector } from 'react-redux';
23
import { getQuerySelector } from '@redux-requests/core';
34

4-
const useQuery = props => {
5-
return useSelector(getQuerySelector(props));
5+
import useDispatchRequest from './use-dispatch-request';
6+
7+
const emptyVariables = [];
8+
9+
const useQuery = ({
10+
variables = emptyVariables,
11+
dispatch = false,
12+
...selectorProps
13+
}) => {
14+
const dispatchRequest = useDispatchRequest();
15+
16+
const dispatchQuery = useCallback(() => {
17+
if (dispatch) {
18+
return dispatchRequest(
19+
(selectorProps.action || selectorProps.type)(...variables),
20+
);
21+
}
22+
23+
return Promise.resolve(null);
24+
}, [dispatch, selectorProps.action, selectorProps.type, ...variables]);
25+
26+
useEffect(() => {
27+
if (dispatch) {
28+
dispatchQuery();
29+
}
30+
}, [dispatch, dispatchQuery]);
31+
32+
return {
33+
...useSelector(getQuerySelector(selectorProps)),
34+
load: dispatchQuery,
35+
};
636
};
737

838
export default useQuery;

packages/redux-requests-react/types/index.d.spec.tsx

+23-8
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,24 @@ import {
99
useDispatchRequest,
1010
} from './index';
1111

12-
const fetchBooks: () => RequestAction<
13-
{ raw: boolean },
14-
{ parsed: boolean }
15-
> = () => {
12+
function fetchBooks(
13+
x: number,
14+
y: string,
15+
z: { a: boolean },
16+
): RequestAction<{ raw: boolean }, { parsed: boolean }> {
1617
return {
1718
type: 'FETCH_BOOKS',
1819
request: {
1920
url: '/books',
21+
x,
22+
y,
23+
a: z.a,
2024
},
2125
meta: {
2226
getData: data => ({ parsed: data.raw }),
2327
},
2428
};
25-
};
29+
}
2630

2731
function fetchBook(id: string): RequestAction<{ id: string; title: string }> {
2832
return {
@@ -34,12 +38,23 @@ function fetchBook(id: string): RequestAction<{ id: string; title: string }> {
3438
}
3539

3640
const query = useQuery<string>({ type: 'Query' });
37-
const query2 = useQuery({
41+
const query2 = useQuery<number>({
3842
type: 'Query',
3943
multiple: true,
4044
defaultData: {},
45+
variables: [{ x: 1, y: 2 }],
4146
});
42-
const query3 = useQuery({ type: fetchBooks });
47+
query2.data;
48+
49+
const query3 = useQuery({
50+
type: fetchBooks,
51+
action: fetchBooks,
52+
dispatch: true,
53+
variables: [1, '1', { a: true }],
54+
});
55+
query3.data;
56+
const x = query3.load();
57+
4358
const query4 = useQuery({ type: 'FETCH_BOOKS', action: fetchBooks });
4459

4560
const mutation = useMutation({ type: 'Mutation' });
@@ -168,7 +183,7 @@ const QueryDispatcher = () => {
168183
return (
169184
<button
170185
onClick={async () => {
171-
const response = await dispatch(fetchBooks());
186+
const response = await dispatch(fetchBooks(1, '1', { a: false }));
172187
response.data.parsed;
173188
const response2 = await dispatch(fetchBook('1'));
174189
response2.data.title;

packages/redux-requests-react/types/index.d.ts

+32-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
QueryState,
44
MutationState,
55
RequestAction,
6-
dispatchRequest,
6+
DispatchRequest,
77
} from '@redux-requests/core';
88

99
interface LoadingProps {
@@ -57,17 +57,43 @@ interface MutationProps {
5757

5858
export class Mutation extends React.Component<MutationProps> {}
5959

60-
export function useQuery<QueryStateData = any>(props: {
61-
type: string | ((...params: any[]) => RequestAction<any, QueryStateData>);
62-
action?: (...params: any[]) => RequestAction<any, QueryStateData>;
60+
interface RequestCreator<QueryStateData = any> {
61+
(...args: any[]): RequestAction<any, QueryStateData>;
62+
}
63+
64+
type GetQueryStateData<T extends RequestCreator> = T extends RequestCreator<
65+
infer QueryStateData
66+
>
67+
? QueryStateData
68+
: never;
69+
70+
export function useQuery<
71+
Data = undefined,
72+
QueryCreator extends RequestCreator = any
73+
>(props: {
74+
type: string | QueryCreator;
75+
action?: QueryCreator;
6376
requestKey?: string;
6477
multiple?: boolean;
6578
defaultData?: any;
66-
}): QueryState<QueryStateData>;
79+
dispatch?: boolean;
80+
variables?: Parameters<QueryCreator>;
81+
}): QueryState<
82+
Data extends undefined ? GetQueryStateData<QueryCreator> : Data
83+
> & {
84+
load: () => Promise<{
85+
data?: QueryState<
86+
Data extends undefined ? GetQueryStateData<QueryCreator> : Data
87+
>;
88+
error?: null;
89+
isAborted?: true;
90+
action: any;
91+
}>;
92+
};
6793

6894
export function useMutation(props: {
6995
type: string | ((...params: any[]) => RequestAction);
7096
requestKey?: string;
7197
}): MutationState;
7298

73-
export function useDispatchRequest(): typeof dispatchRequest;
99+
export function useDispatchRequest(): DispatchRequest;

packages/redux-requests/types/index.d.ts

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { AnyAction, Reducer, Middleware, Store } from 'redux';
22

3-
export function dispatchRequest<QueryStateData = any>(
4-
requestAction: RequestAction<any, QueryStateData>,
5-
): Promise<{
6-
data?: QueryStateData;
7-
error?: null;
8-
isAborted?: true;
9-
action: any;
10-
}>;
3+
export interface DispatchRequest {
4+
<QueryStateData = any>(
5+
requestAction: RequestAction<any, QueryStateData>,
6+
): Promise<{
7+
data?: QueryStateData;
8+
error?: null;
9+
isAborted?: true;
10+
action: any;
11+
}>;
12+
}
1113

1214
interface FilterActions {
1315
(action: AnyAction): boolean;
@@ -18,7 +20,7 @@ interface ModifyData {
1820
}
1921

2022
interface RequestsStore extends Store {
21-
dispatchRequest: typeof dispatchRequest;
23+
dispatchRequest: DispatchRequest;
2224
}
2325

2426
export const createRequestsStore: (store: Store) => RequestsStore;

0 commit comments

Comments
 (0)