feat: add response to state

This commit is contained in:
Dmitriy Pleshevskiy 2021-06-17 22:43:29 +03:00
parent 3d8898f333
commit 3c1582ef9f
5 changed files with 29 additions and 55 deletions

View file

@ -104,8 +104,8 @@ export function useLazyRequest<E extends AnyEndpoint>(
return Promise.resolve(state.data); return Promise.resolve(state.data);
} }
const onComplete = handlerConfig?.onComplete ?? config?.onComplete; const onCompletes = [config?.onComplete, handlerConfig?.onComplete].filter(isFunction);
const onFailure = handlerConfig?.onFailure ?? config?.onFailure; const onFailures = [config?.onFailure, handlerConfig?.onFailure].filter(isFunction);
dispatch({ type: 'call', headers, variables, params }); dispatch({ type: 'call', headers, variables, params });
@ -123,17 +123,15 @@ export function useLazyRequest<E extends AnyEndpoint>(
(response) => { (response) => {
dispatch({ type: 'success', response }); dispatch({ type: 'success', response });
if (isFunction(onComplete)) { onCompletes.forEach(cb => cb(response.data));
onComplete(response.data);
}
return response.data; return response.data;
}, },
(response: ClientResponse<ExtractEndpointResponse<E>>) => { (response: ClientResponse<ExtractEndpointResponse<E>>) => {
dispatch({ type: 'failure', response }); dispatch({ type: 'failure', response });
if (!response.canceled && isFunction(onFailure)) { if (!response.canceled) {
onFailure(response); onFailures.forEach(cb => cb(response));
} }
return null; return null;
@ -172,7 +170,7 @@ export function useLazyRequest<E extends AnyEndpoint>(
loading: state.loading, loading: state.loading,
isCalled: state.isCalled, isCalled: state.isCalled,
isCanceled: state.isCanceled, isCanceled: state.isCanceled,
error: state.error, fetchError: state.fetchError,
refetch, refetch,
cancel: client.cancelRequest.bind(client), cancel: client.cancelRequest.bind(client),
}, },

View file

@ -5,7 +5,8 @@ export type PublicRequestState<R> = Readonly<{
loading: boolean; loading: boolean;
isCalled: boolean; isCalled: boolean;
isCanceled?: boolean; isCanceled?: boolean;
error?: Error; response?: ClientResponse<R>;
fetchError?: Error;
}>; }>;
export type RequestState<R> = PublicRequestState<R> & Readonly<{ export type RequestState<R> = PublicRequestState<R> & Readonly<{
@ -35,12 +36,13 @@ export type RequestAction<R> =
export type RequestReducer<R> = React.Reducer<RequestState<R>, RequestAction<R>> export type RequestReducer<R> = React.Reducer<RequestState<R>, RequestAction<R>>
export function requestReducer<R>(state: RequestState<R>, action: RequestAction<R>) { export function requestReducer<R>(state: RequestState<R>, action: RequestAction<R>): RequestState<R> {
switch (action.type) { switch (action.type) {
case 'call': { case 'call': {
return { return {
...state, ...state,
error: undefined, response: undefined,
fetchError: undefined,
isCanceled: false, isCanceled: false,
loading: true, loading: true,
isCalled: true, isCalled: true,
@ -53,6 +55,7 @@ export function requestReducer<R>(state: RequestState<R>, action: RequestAction<
return { return {
...state, ...state,
loading: false, loading: false,
response: action.response,
data: action.response.data, data: action.response.data,
}; };
} }
@ -60,8 +63,9 @@ export function requestReducer<R>(state: RequestState<R>, action: RequestAction<
return { return {
...state, ...state,
loading: false, loading: false,
response: action.response,
data: null, data: null,
error: action.response.error, fetchError: action.response.error,
isCanceled: action.response.canceled, isCanceled: action.response.canceled,
}; };
} }
@ -69,7 +73,7 @@ export function requestReducer<R>(state: RequestState<R>, action: RequestAction<
return { return {
...state, ...state,
isCanceled: false, isCanceled: false,
error: undefined, fetchError: undefined,
}; };
} }
} }

View file

@ -20,7 +20,7 @@ export function useLazyRequest(endpoint, config) {
: data; : data;
}, [endpoint]); }, [endpoint]);
const handler = React.useCallback((handlerConfig) => { const handler = React.useCallback((handlerConfig) => {
var _a, _b, _c; var _a;
if ((state === null || state === void 0 ? void 0 : state.loading) || (state === null || state === void 0 ? void 0 : state.isCanceled)) { if ((state === null || state === void 0 ? void 0 : state.loading) || (state === null || state === void 0 ? void 0 : state.isCanceled)) {
return Promise.resolve(null); return Promise.resolve(null);
} }
@ -45,8 +45,8 @@ export function useLazyRequest(endpoint, config) {
&& !(handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.force)) { && !(handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.force)) {
return Promise.resolve(state.data); return Promise.resolve(state.data);
} }
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 onCompletes = [config === null || config === void 0 ? void 0 : config.onComplete, handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.onComplete].filter(isFunction);
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 onFailures = [config === null || config === void 0 ? void 0 : config.onFailure, handlerConfig === null || handlerConfig === void 0 ? void 0 : handlerConfig.onFailure].filter(isFunction);
dispatch({ type: 'call', headers, variables, params }); dispatch({ type: 'call', headers, variables, params });
setPrevHandlerConfig(handlerConfig !== null && handlerConfig !== void 0 ? handlerConfig : {}); setPrevHandlerConfig(handlerConfig !== null && handlerConfig !== void 0 ? handlerConfig : {});
return client return client
@ -55,14 +55,12 @@ export function useLazyRequest(endpoint, config) {
transformResponseData })) transformResponseData }))
.then((response) => { .then((response) => {
dispatch({ type: 'success', response }); dispatch({ type: 'success', response });
if (isFunction(onComplete)) { onCompletes.forEach(cb => cb(response.data));
onComplete(response.data);
}
return response.data; return response.data;
}, (response) => { }, (response) => {
dispatch({ type: 'failure', response }); dispatch({ type: 'failure', response });
if (!response.canceled && isFunction(onFailure)) { if (!response.canceled) {
onFailure(response); onFailures.forEach(cb => cb(response));
} }
return null; return null;
}); });
@ -85,7 +83,7 @@ export function useLazyRequest(endpoint, config) {
loading: state.loading, loading: state.loading,
isCalled: state.isCalled, isCalled: state.isCalled,
isCanceled: state.isCanceled, isCanceled: state.isCanceled,
error: state.error, fetchError: state.fetchError,
refetch, refetch,
cancel: client.cancelRequest.bind(client), cancel: client.cancelRequest.bind(client),
}, },

32
target/reducer.d.ts vendored
View file

@ -5,7 +5,8 @@ export declare type PublicRequestState<R> = Readonly<{
loading: boolean; loading: boolean;
isCalled: boolean; isCalled: boolean;
isCanceled?: boolean; isCanceled?: boolean;
error?: Error; response?: ClientResponse<R>;
fetchError?: Error;
}>; }>;
export declare type RequestState<R> = PublicRequestState<R> & Readonly<{ export declare type RequestState<R> = PublicRequestState<R> & Readonly<{
prevHeaders?: Record<string, string>; prevHeaders?: Record<string, string>;
@ -27,31 +28,4 @@ export declare type RequestAction<R> = {
type: 'cancel'; type: 'cancel';
}; };
export declare type RequestReducer<R> = React.Reducer<RequestState<R>, RequestAction<R>>; export declare type RequestReducer<R> = React.Reducer<RequestState<R>, RequestAction<R>>;
export declare function requestReducer<R>(state: RequestState<R>, action: RequestAction<R>): { export declare function requestReducer<R>(state: RequestState<R>, action: RequestAction<R>): RequestState<R>;
loading: boolean;
data: R;
isCalled: boolean;
isCanceled?: boolean | undefined;
error?: Error | undefined;
prevHeaders?: Record<string, string> | undefined;
prevVariables?: Record<string, any> | undefined;
prevParams?: Record<string, any> | undefined;
} | {
loading: boolean;
data: null;
error: Error | undefined;
isCanceled: boolean | undefined;
isCalled: boolean;
prevHeaders?: Record<string, string> | undefined;
prevVariables?: Record<string, any> | undefined;
prevParams?: Record<string, any> | undefined;
} | {
isCanceled: boolean;
error: undefined;
data: R | null;
loading: boolean;
isCalled: boolean;
prevHeaders?: Record<string, string> | undefined;
prevVariables?: Record<string, any> | undefined;
prevParams?: Record<string, any> | undefined;
};

View file

@ -1,16 +1,16 @@
export function requestReducer(state, action) { export function requestReducer(state, action) {
switch (action.type) { switch (action.type) {
case 'call': { case 'call': {
return Object.assign(Object.assign({}, state), { error: undefined, isCanceled: false, loading: true, isCalled: true, prevHeaders: action.headers, prevVariables: action.variables, prevParams: action.params }); return Object.assign(Object.assign({}, state), { response: undefined, fetchError: undefined, isCanceled: false, loading: true, isCalled: true, prevHeaders: action.headers, prevVariables: action.variables, prevParams: action.params });
} }
case 'success': { case 'success': {
return Object.assign(Object.assign({}, state), { loading: false, data: action.response.data }); return Object.assign(Object.assign({}, state), { loading: false, response: action.response, data: action.response.data });
} }
case 'failure': { case 'failure': {
return Object.assign(Object.assign({}, state), { loading: false, data: null, error: action.response.error, isCanceled: action.response.canceled }); return Object.assign(Object.assign({}, state), { loading: false, response: action.response, data: null, fetchError: action.response.error, isCanceled: action.response.canceled });
} }
case 'cancel': { case 'cancel': {
return Object.assign(Object.assign({}, state), { isCanceled: false, error: undefined }); return Object.assign(Object.assign({}, state), { isCanceled: false, fetchError: undefined });
} }
} }
} }