Merge pull request #23 from pleshevskiy/task-22
feat: add refetch function to hooks state
This commit is contained in:
commit
70da8b3ad0
8 changed files with 63 additions and 25 deletions
|
@ -8,7 +8,7 @@ export enum Method {
|
||||||
DELETE = 'DELETE',
|
DELETE = 'DELETE',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Endpoint<R, V, P = never> = Readonly<{
|
export type Endpoint<R, _V, P = never> = Readonly<{
|
||||||
method: Method;
|
method: Method;
|
||||||
url: string | ((params: P) => string);
|
url: string | ((params: P) => string);
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useCallback, useMemo } from 'react';
|
import React from 'react';
|
||||||
import invariant from 'tiny-invariant';
|
import invariant from 'tiny-invariant';
|
||||||
import isEqual from 'lodash.isequal';
|
import isEqual from 'lodash.isequal';
|
||||||
import { useClient } from './client-hook';
|
import { useClient } from './client-hook';
|
||||||
|
@ -23,6 +23,10 @@ export type LazyRequestHandlerConfig<R, V, P> = Readonly<
|
||||||
|
|
||||||
export type RequestHandler<R, V, P> = (config?: LazyRequestHandlerConfig<R, V, P>) => Promise<R | null>;
|
export type RequestHandler<R, V, P> = (config?: LazyRequestHandlerConfig<R, V, P>) => Promise<R | null>;
|
||||||
|
|
||||||
|
export type RefetchRequestHandler = () => void;
|
||||||
|
|
||||||
|
export type PublicRequestStateWithRefetch<R> = PublicRequestState<R> & { refetch: RefetchRequestHandler };
|
||||||
|
|
||||||
export function useLazyRequest<
|
export function useLazyRequest<
|
||||||
E extends Endpoint<R, V, P>,
|
E extends Endpoint<R, V, P>,
|
||||||
R = ExtractEndpointResponse<E>,
|
R = ExtractEndpointResponse<E>,
|
||||||
|
@ -31,7 +35,7 @@ export function useLazyRequest<
|
||||||
>(
|
>(
|
||||||
endpoint: E,
|
endpoint: E,
|
||||||
config?: LazyRequestConfig<R, V, P>,
|
config?: LazyRequestConfig<R, V, P>,
|
||||||
): [RequestHandler<R, V, P>, PublicRequestState<R>] {
|
): [RequestHandler<R, V, P>, PublicRequestStateWithRefetch<R>] {
|
||||||
const [client] = useClient();
|
const [client] = useClient();
|
||||||
const { defaultHeaders } = useRequestContext();
|
const { defaultHeaders } = useRequestContext();
|
||||||
const [state, dispatch] = React.useReducer<React.Reducer<RequestState<R>, RequestAction<R>>>(
|
const [state, dispatch] = React.useReducer<React.Reducer<RequestState<R>, RequestAction<R>>>(
|
||||||
|
@ -42,8 +46,9 @@ export function useLazyRequest<
|
||||||
isCalled: false,
|
isCalled: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
const [prevHandlerConfig, setPrevHandlerConfig] = React.useState<LazyRequestHandlerConfig<R, V, P> | null>(null);
|
||||||
|
|
||||||
const transformResponseData = useCallback(
|
const transformResponseData = React.useCallback(
|
||||||
(data: unknown): R => {
|
(data: unknown): R => {
|
||||||
return isFunction(endpoint.transformResponseData) ?
|
return isFunction(endpoint.transformResponseData) ?
|
||||||
endpoint.transformResponseData(data)
|
endpoint.transformResponseData(data)
|
||||||
|
@ -98,6 +103,8 @@ export function useLazyRequest<
|
||||||
|
|
||||||
dispatch({ type: 'call', headers, variables, params });
|
dispatch({ type: 'call', headers, variables, params });
|
||||||
|
|
||||||
|
setPrevHandlerConfig(handlerConfig ?? {});
|
||||||
|
|
||||||
return client
|
return client
|
||||||
.request<R>({
|
.request<R>({
|
||||||
...endpoint,
|
...endpoint,
|
||||||
|
@ -128,12 +135,25 @@ export function useLazyRequest<
|
||||||
[state, config, client, endpoint, defaultHeaders, transformResponseData]
|
[state, config, client, endpoint, defaultHeaders, transformResponseData]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const refetch = React.useCallback(
|
||||||
|
() => {
|
||||||
|
if (prevHandlerConfig != null) {
|
||||||
|
handler({
|
||||||
|
...prevHandlerConfig,
|
||||||
|
force: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[handler, prevHandlerConfig]
|
||||||
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
handler,
|
handler,
|
||||||
{
|
{
|
||||||
data: state.data,
|
data: state.data,
|
||||||
loading: state.loading,
|
loading: state.loading,
|
||||||
isCalled: state.isCalled,
|
isCalled: state.isCalled,
|
||||||
|
refetch,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,32 @@
|
||||||
import { ClientResponse } from './client';
|
import { ClientResponse } from './client';
|
||||||
|
|
||||||
export type RequestState<R> = Readonly<{
|
export type PublicRequestState<R> = Readonly<{
|
||||||
data: R | null;
|
data: R | null;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
isCalled: boolean;
|
isCalled: boolean;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type RequestState<R> = PublicRequestState<R> & Readonly<{
|
||||||
prevHeaders?: Record<string, string>;
|
prevHeaders?: Record<string, string>;
|
||||||
prevVariables?: Record<string, any>;
|
prevVariables?: Record<string, any>;
|
||||||
prevParams?: Record<string, any>
|
prevParams?: Record<string, any>;
|
||||||
}>
|
}>
|
||||||
|
|
||||||
export type PublicRequestState<R> = Pick<RequestState<R>, 'data' | 'loading' | 'isCalled'>;
|
|
||||||
|
|
||||||
export type RequestAction<R> =
|
export type RequestAction<R> =
|
||||||
| { type: 'call', headers: Record<string, string>, variables: Record<string, any>, params?: Record<string, any> }
|
| {
|
||||||
| { type: 'success', response: ClientResponse<R> }
|
type: 'call',
|
||||||
| { type: 'failure', response: ClientResponse<R> }
|
headers: Record<string, string>,
|
||||||
|
variables: Record<string, any>,
|
||||||
|
params?: Record<string, any>
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'success',
|
||||||
|
response: ClientResponse<R>
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'failure',
|
||||||
|
response: ClientResponse<R>
|
||||||
|
}
|
||||||
|
|
||||||
export function requestReducer<R>(state: RequestState<R>, action: RequestAction<R>) {
|
export function requestReducer<R>(state: RequestState<R>, action: RequestAction<R>) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
|
2
target/endpoint.d.ts
vendored
2
target/endpoint.d.ts
vendored
|
@ -6,7 +6,7 @@ export declare enum Method {
|
||||||
PATCH = "PATCH",
|
PATCH = "PATCH",
|
||||||
DELETE = "DELETE"
|
DELETE = "DELETE"
|
||||||
}
|
}
|
||||||
export declare type Endpoint<R, V, P = never> = Readonly<{
|
export declare type Endpoint<R, _V, P = never> = Readonly<{
|
||||||
method: Method;
|
method: Method;
|
||||||
url: string | ((params: P) => string);
|
url: string | ((params: P) => string);
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
|
|
6
target/lazy-request-hook.d.ts
vendored
6
target/lazy-request-hook.d.ts
vendored
|
@ -12,4 +12,8 @@ export declare type LazyRequestHandlerConfig<R, V, P> = Readonly<LazyRequestConf
|
||||||
force?: boolean;
|
force?: boolean;
|
||||||
}>;
|
}>;
|
||||||
export declare type RequestHandler<R, V, P> = (config?: LazyRequestHandlerConfig<R, V, P>) => Promise<R | null>;
|
export declare type RequestHandler<R, V, P> = (config?: LazyRequestHandlerConfig<R, V, P>) => Promise<R | null>;
|
||||||
export declare function useLazyRequest<E extends Endpoint<R, V, P>, R = ExtractEndpointResponse<E>, V = ExtractEndpointVariables<E>, P = ExtractEndpointParams<E>>(endpoint: E, config?: LazyRequestConfig<R, V, P>): [RequestHandler<R, V, P>, PublicRequestState<R>];
|
export declare type RefetchRequestHandler = () => void;
|
||||||
|
export declare type PublicRequestStateWithRefetch<R> = PublicRequestState<R> & {
|
||||||
|
refetch: RefetchRequestHandler;
|
||||||
|
};
|
||||||
|
export declare function useLazyRequest<E extends Endpoint<R, V, P>, R = ExtractEndpointResponse<E>, V = ExtractEndpointVariables<E>, P = ExtractEndpointParams<E>>(endpoint: E, config?: LazyRequestConfig<R, V, P>): [RequestHandler<R, V, P>, PublicRequestStateWithRefetch<R>];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useCallback } from 'react';
|
import React from 'react';
|
||||||
import invariant from 'tiny-invariant';
|
import invariant from 'tiny-invariant';
|
||||||
import isEqual from 'lodash.isequal';
|
import isEqual from 'lodash.isequal';
|
||||||
import { useClient } from './client-hook';
|
import { useClient } from './client-hook';
|
||||||
|
@ -13,7 +13,8 @@ export function useLazyRequest(endpoint, config) {
|
||||||
loading: false,
|
loading: false,
|
||||||
isCalled: false,
|
isCalled: false,
|
||||||
});
|
});
|
||||||
const transformResponseData = useCallback((data) => {
|
const [prevHandlerConfig, setPrevHandlerConfig] = React.useState(null);
|
||||||
|
const transformResponseData = React.useCallback((data) => {
|
||||||
return isFunction(endpoint.transformResponseData) ?
|
return isFunction(endpoint.transformResponseData) ?
|
||||||
endpoint.transformResponseData(data)
|
endpoint.transformResponseData(data)
|
||||||
: data;
|
: data;
|
||||||
|
@ -46,6 +47,7 @@ export function useLazyRequest(endpoint, config) {
|
||||||
const onComplete = (_b = handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.onComplete) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config.onComplete;
|
const onComplete = (_b = handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.onComplete) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config.onComplete;
|
||||||
const onFailure = (_c = handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.onFailure) !== null && _c !== void 0 ? _c : config === null || config === void 0 ? void 0 : config.onFailure;
|
const onFailure = (_c = handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.onFailure) !== null && _c !== void 0 ? _c : config === null || config === void 0 ? void 0 : config.onFailure;
|
||||||
dispatch({ type: 'call', headers, variables, params });
|
dispatch({ type: 'call', headers, variables, params });
|
||||||
|
setPrevHandlerConfig(handlerConfig !== null && handlerConfig !== void 0 ? handlerConfig : {});
|
||||||
return client
|
return client
|
||||||
.request(Object.assign(Object.assign({}, endpoint), { url: endpointUrl, headers,
|
.request(Object.assign(Object.assign({}, endpoint), { url: endpointUrl, headers,
|
||||||
variables,
|
variables,
|
||||||
|
@ -64,12 +66,18 @@ export function useLazyRequest(endpoint, config) {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}, [state, config, client, endpoint, defaultHeaders, transformResponseData]);
|
}, [state, config, client, endpoint, defaultHeaders, transformResponseData]);
|
||||||
|
const refetch = React.useCallback(() => {
|
||||||
|
if (prevHandlerConfig != null) {
|
||||||
|
handler(Object.assign(Object.assign({}, prevHandlerConfig), { force: true }));
|
||||||
|
}
|
||||||
|
}, [handler, prevHandlerConfig]);
|
||||||
return [
|
return [
|
||||||
handler,
|
handler,
|
||||||
{
|
{
|
||||||
data: state.data,
|
data: state.data,
|
||||||
loading: state.loading,
|
loading: state.loading,
|
||||||
isCalled: state.isCalled,
|
isCalled: state.isCalled,
|
||||||
|
refetch,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
5
target/reducer.d.ts
vendored
5
target/reducer.d.ts
vendored
|
@ -1,13 +1,14 @@
|
||||||
import { ClientResponse } from './client';
|
import { ClientResponse } from './client';
|
||||||
export declare type RequestState<R> = Readonly<{
|
export declare type PublicRequestState<R> = Readonly<{
|
||||||
data: R | null;
|
data: R | null;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
isCalled: boolean;
|
isCalled: boolean;
|
||||||
|
}>;
|
||||||
|
export declare type RequestState<R> = PublicRequestState<R> & Readonly<{
|
||||||
prevHeaders?: Record<string, string>;
|
prevHeaders?: Record<string, string>;
|
||||||
prevVariables?: Record<string, any>;
|
prevVariables?: Record<string, any>;
|
||||||
prevParams?: Record<string, any>;
|
prevParams?: Record<string, any>;
|
||||||
}>;
|
}>;
|
||||||
export declare type PublicRequestState<R> = Pick<RequestState<R>, 'data' | 'loading' | 'isCalled'>;
|
|
||||||
export declare type RequestAction<R> = {
|
export declare type RequestAction<R> = {
|
||||||
type: 'call';
|
type: 'call';
|
||||||
headers: Record<string, string>;
|
headers: Record<string, string>;
|
||||||
|
|
9
target/request-hook.d.ts
vendored
9
target/request-hook.d.ts
vendored
|
@ -3,11 +3,4 @@ import { LazyRequestConfig } from './lazy-request-hook';
|
||||||
export declare type RequestConfig<R, V, P> = Readonly<LazyRequestConfig<R, V, P> & {
|
export declare type RequestConfig<R, V, P> = Readonly<LazyRequestConfig<R, V, P> & {
|
||||||
skip?: boolean;
|
skip?: boolean;
|
||||||
}>;
|
}>;
|
||||||
export declare function useRequest<E extends Endpoint<R, V, P>, R = ExtractEndpointResponse<E>, V = ExtractEndpointVariables<E>, P = ExtractEndpointParams<E>>(endpoint: E, config?: RequestConfig<R, V, P>): Pick<Readonly<{
|
export declare function useRequest<E extends Endpoint<R, V, P>, R = ExtractEndpointResponse<E>, V = ExtractEndpointVariables<E>, P = ExtractEndpointParams<E>>(endpoint: E, config?: RequestConfig<R, V, P>): import("./lazy-request-hook").PublicRequestStateWithRefetch<R>;
|
||||||
data: R | null;
|
|
||||||
loading: boolean;
|
|
||||||
isCalled: boolean;
|
|
||||||
prevHeaders?: Record<string, string> | undefined;
|
|
||||||
prevVariables?: Record<string, any> | undefined;
|
|
||||||
prevParams?: Record<string, any> | undefined;
|
|
||||||
}>, "loading" | "data" | "isCalled">;
|
|
||||||
|
|
Reference in a new issue