68 lines
1.6 KiB
TypeScript
68 lines
1.6 KiB
TypeScript
/* eslint-disable react-hooks/set-state-in-effect */
|
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { Photo } from '.';
|
|
import { useDebounce } from 'use-debounce';
|
|
import { getPhotosAction, searchPhotosPublicAction } from './actions';
|
|
|
|
const formatQuery = (query: string) =>
|
|
query.trim().toLocaleLowerCase();
|
|
|
|
export default function usePhotoQuery({
|
|
query,
|
|
isEnabled = true,
|
|
minimumQueryLength = 2,
|
|
isPrivate,
|
|
}: {
|
|
query: string
|
|
isEnabled?: boolean
|
|
minimumQueryLength?: number
|
|
isPrivate?: boolean
|
|
}) {
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
const queryFormatted = useMemo(() =>
|
|
formatQuery(query), [query]);
|
|
const [_queryDebounced] = useDebounce(query, 500, { leading: true });
|
|
const queryDebounced = useMemo(() =>
|
|
formatQuery(_queryDebounced), [_queryDebounced]);
|
|
|
|
const [photos, setPhotos] = useState<Photo[]>([]);
|
|
|
|
const reset = useCallback(() => {
|
|
setPhotos([]);
|
|
setIsLoading(false);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (queryDebounced.length >= minimumQueryLength && isEnabled) {
|
|
setIsLoading(true);
|
|
(isPrivate
|
|
? getPhotosAction({ query: queryDebounced })
|
|
: searchPhotosPublicAction(queryDebounced))
|
|
.then(setPhotos)
|
|
.finally(() => setIsLoading(false));
|
|
}
|
|
}, [
|
|
queryDebounced,
|
|
minimumQueryLength,
|
|
isEnabled,
|
|
isPrivate,
|
|
]);
|
|
|
|
useEffect(() => {
|
|
if (queryFormatted.length >= minimumQueryLength) {
|
|
setIsLoading(true);
|
|
} else {
|
|
setPhotos([]);
|
|
setIsLoading(false);
|
|
}
|
|
}, [minimumQueryLength, queryFormatted]);
|
|
|
|
return {
|
|
queryFormatted,
|
|
photos,
|
|
isLoading,
|
|
reset,
|
|
};
|
|
}
|