parent
d4e83748c3
commit
a1afb6b599
8 changed files with 63 additions and 25 deletions
|
@ -8,7 +8,7 @@ export enum Method {
|
|||
DELETE = 'DELETE',
|
||||
}
|
||||
|
||||
export type Endpoint<R, V, P = never> = Readonly<{
|
||||
export type Endpoint<R, _V, P = never> = Readonly<{
|
||||
method: Method;
|
||||
url: string | ((params: P) => 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 isEqual from 'lodash.isequal';
|
||||
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 RefetchRequestHandler = () => void;
|
||||
|
||||
export type PublicRequestStateWithRefetch<R> = PublicRequestState<R> & { refetch: RefetchRequestHandler };
|
||||
|
||||
export function useLazyRequest<
|
||||
E extends Endpoint<R, V, P>,
|
||||
R = ExtractEndpointResponse<E>,
|
||||
|
@ -31,7 +35,7 @@ export function useLazyRequest<
|
|||
>(
|
||||
endpoint: E,
|
||||
config?: LazyRequestConfig<R, V, P>,
|
||||
): [RequestHandler<R, V, P>, PublicRequestState<R>] {
|
||||
): [RequestHandler<R, V, P>, PublicRequestStateWithRefetch<R>] {
|
||||
const [client] = useClient();
|
||||
const { defaultHeaders } = useRequestContext();
|
||||
const [state, dispatch] = React.useReducer<React.Reducer<RequestState<R>, RequestAction<R>>>(
|
||||
|
@ -42,8 +46,9 @@ export function useLazyRequest<
|
|||
isCalled: false,
|
||||
}
|
||||
);
|
||||
const [prevHandlerConfig, setPrevHandlerConfig] = React.useState<LazyRequestHandlerConfig<R, V, P> | null>(null);
|
||||
|
||||
const transformResponseData = useCallback(
|
||||
const transformResponseData = React.useCallback(
|
||||
(data: unknown): R => {
|
||||
return isFunction(endpoint.transformResponseData) ?
|
||||
endpoint.transformResponseData(data)
|
||||
|
@ -98,6 +103,8 @@ export function useLazyRequest<
|
|||
|
||||
dispatch({ type: 'call', headers, variables, params });
|
||||
|
||||
setPrevHandlerConfig(handlerConfig ?? {});
|
||||
|
||||
return client
|
||||
.request<R>({
|
||||
...endpoint,
|
||||
|
@ -128,12 +135,25 @@ export function useLazyRequest<
|
|||
[state, config, client, endpoint, defaultHeaders, transformResponseData]
|
||||
);
|
||||
|
||||
const refetch = React.useCallback(
|
||||
() => {
|
||||
if (prevHandlerConfig != null) {
|
||||
handler({
|
||||
...prevHandlerConfig,
|
||||
force: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
[handler, prevHandlerConfig]
|
||||
);
|
||||
|
||||
return [
|
||||
handler,
|
||||
{
|
||||
data: state.data,
|
||||
loading: state.loading,
|
||||
isCalled: state.isCalled,
|
||||
refetch,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,20 +1,32 @@
|
|||
import { ClientResponse } from './client';
|
||||
|
||||
export type RequestState<R> = Readonly<{
|
||||
export type PublicRequestState<R> = Readonly<{
|
||||
data: R | null;
|
||||
loading: boolean;
|
||||
isCalled: boolean;
|
||||
}>;
|
||||
|
||||
export type RequestState<R> = PublicRequestState<R> & Readonly<{
|
||||
prevHeaders?: Record<string, string>;
|
||||
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> =
|
||||
| { type: 'call', headers: Record<string, string>, variables: Record<string, any>, params?: Record<string, any> }
|
||||
| { type: 'success', response: ClientResponse<R> }
|
||||
| { type: 'failure', response: ClientResponse<R> }
|
||||
| {
|
||||
type: 'call',
|
||||
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>) {
|
||||
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",
|
||||
DELETE = "DELETE"
|
||||
}
|
||||
export declare type Endpoint<R, V, P = never> = Readonly<{
|
||||
export declare type Endpoint<R, _V, P = never> = Readonly<{
|
||||
method: Method;
|
||||
url: string | ((params: P) => 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;
|
||||
}>;
|
||||
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 isEqual from 'lodash.isequal';
|
||||
import { useClient } from './client-hook';
|
||||
|
@ -13,7 +13,8 @@ export function useLazyRequest(endpoint, config) {
|
|||
loading: false,
|
||||
isCalled: false,
|
||||
});
|
||||
const transformResponseData = useCallback((data) => {
|
||||
const [prevHandlerConfig, setPrevHandlerConfig] = React.useState(null);
|
||||
const transformResponseData = React.useCallback((data) => {
|
||||
return isFunction(endpoint.transformResponseData) ?
|
||||
endpoint.transformResponseData(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 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 });
|
||||
setPrevHandlerConfig(handlerConfig !== null && handlerConfig !== void 0 ? handlerConfig : {});
|
||||
return client
|
||||
.request(Object.assign(Object.assign({}, endpoint), { url: endpointUrl, headers,
|
||||
variables,
|
||||
|
@ -64,12 +66,18 @@ export function useLazyRequest(endpoint, config) {
|
|||
return null;
|
||||
});
|
||||
}, [state, config, client, endpoint, defaultHeaders, transformResponseData]);
|
||||
const refetch = React.useCallback(() => {
|
||||
if (prevHandlerConfig != null) {
|
||||
handler(Object.assign(Object.assign({}, prevHandlerConfig), { force: true }));
|
||||
}
|
||||
}, [handler, prevHandlerConfig]);
|
||||
return [
|
||||
handler,
|
||||
{
|
||||
data: state.data,
|
||||
loading: state.loading,
|
||||
isCalled: state.isCalled,
|
||||
refetch,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
5
target/reducer.d.ts
vendored
5
target/reducer.d.ts
vendored
|
@ -1,13 +1,14 @@
|
|||
import { ClientResponse } from './client';
|
||||
export declare type RequestState<R> = Readonly<{
|
||||
export declare type PublicRequestState<R> = Readonly<{
|
||||
data: R | null;
|
||||
loading: boolean;
|
||||
isCalled: boolean;
|
||||
}>;
|
||||
export declare type RequestState<R> = PublicRequestState<R> & Readonly<{
|
||||
prevHeaders?: Record<string, string>;
|
||||
prevVariables?: Record<string, any>;
|
||||
prevParams?: Record<string, any>;
|
||||
}>;
|
||||
export declare type PublicRequestState<R> = Pick<RequestState<R>, 'data' | 'loading' | 'isCalled'>;
|
||||
export declare type RequestAction<R> = {
|
||||
type: 'call';
|
||||
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> & {
|
||||
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<{
|
||||
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">;
|
||||
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>;
|
||||
|
|
Reference in a new issue