Created
February 29, 2024 01:07
-
-
Save itproto/d2d5624e42c9bc40916990b81502cae4 to your computer and use it in GitHub Desktop.
AXIS.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useState, useEffect, useRef, useCallback } from 'react'; | |
| // useAsync | |
| type Status = 'idle' | 'pending' | 'success' | 'error'; | |
| interface UseAsyncState<T> { | |
| status: Status; | |
| data?: T; | |
| error?: Error; | |
| } | |
| function useAsync<T>(asyncFunction: () => Promise<T>, dependencies: any[] = []): UseAsyncState<T> { | |
| const [state, setState] = useState<UseAsyncState<T>>({ status: 'idle' }); | |
| useEffect(() => { | |
| let mounted = true; | |
| setState({ status: 'pending' }); | |
| asyncFunction().then( | |
| data => mounted && setState({ status: 'success', data }), | |
| error => mounted && setState({ status: 'error', error }) | |
| ); | |
| return () => { mounted = false; }; | |
| }, dependencies); | |
| return state; | |
| } | |
| // useDebounce | |
| function useDebounce<T>(value: T, delay: number): T { | |
| const [debouncedValue, setDebouncedValue] = useState<T>(value); | |
| useEffect(() => { | |
| const handler = setTimeout(() => setDebouncedValue(value), delay); | |
| return () => clearTimeout(handler); | |
| }, [value, delay]); | |
| return debouncedValue; | |
| } | |
| // useEventListener | |
| function useEventListener<K extends keyof WindowEventMap>( | |
| eventName: K, | |
| handler: (event: WindowEventMap[K]) => void, | |
| element: Window | Document | HTMLElement = window, | |
| ) { | |
| useEffect(() => { | |
| const eventListener = (event: WindowEventMap[K]) => handler(event); | |
| element.addEventListener(eventName, eventListener); | |
| return () => element.removeEventListener(eventName, eventListener); | |
| }, [eventName, element, handler]); | |
| } | |
| // useLocalStorage | |
| function useLocalStorage<T>(key: string, initialValue: T) { | |
| const [storedValue, setStoredValue] = useState<T>(() => { | |
| try { | |
| const item = window.localStorage.getItem(key); | |
| return item ? JSON.parse(item) : initialValue; | |
| } catch (error) { | |
| console.error(error); | |
| return initialValue; | |
| } | |
| }); | |
| const setValue = (value: T | ((val: T) => T)) => { | |
| try { | |
| const valueToStore = value instanceof Function ? value(storedValue) : value; | |
| setStoredValue(valueToStore); | |
| window.localStorage.setItem(key, JSON.stringify(valueToStore)); | |
| } catch (error) { | |
| console.error(error); | |
| } | |
| }; | |
| return [storedValue, setValue] as const; | |
| } | |
| // useMediaQuery | |
| function useMediaQuery(query: string) { | |
| const [matches, setMatches] = useState<boolean>(window.matchMedia(query).matches); | |
| useEffect(() => { | |
| const mediaQueryList = window.matchMedia(query); | |
| const listener = (e: MediaQueryListEvent) => setMatches(e.matches); | |
| mediaQueryList.addEventListener('change', listener); | |
| return () => mediaQueryList.removeEventListener('change', listener); | |
| }, [query]); | |
| return matches; | |
| } | |
| // useOnClickOutside | |
| function useOnClickOutside<T extends HTMLElement>(ref: React.RefObject<T>, handler: (event: MouseEvent | TouchEvent) => void) { | |
| useEffect(() => { | |
| const listener = (event: MouseEvent | TouchEvent) => { | |
| if (!ref.current || ref.current.contains(event.target as Node)) { | |
| return; | |
| } | |
| handler(event); | |
| }; | |
| document.addEventListener('mousedown', listener); | |
| document.addEventListener('touchstart', listener); | |
| return () => { | |
| document.removeEventListener('mousedown', listener); | |
| document.removeEventListener('touchstart', listener); | |
| }; | |
| }, [ref, handler]); | |
| } | |
| // usePrevious | |
| function usePrevious<T>(value: T) { | |
| const ref = useRef<T>(); | |
| useEffect(() => { | |
| ref.current = value; | |
| }, [value]); | |
| return ref.current; | |
| } | |
| // useToggle | |
| function useToggle(initialState: boolean = false): [boolean, () => void] { | |
| const [state, setState] = useState<boolean>(initialState); | |
| const toggle = useCallback(() => setState(state => !state), []); | |
| return [state, toggle]; | |
| } | |
| // useUpdateEffect | |
| function useUpdateEffect(effect: React.EffectCallback, dependencies?: React.DependencyList) { | |
| const isInitialMount = useRef<boolean>(true); | |
| useEffect(() => { | |
| if (isInitialMount.current) { | |
| isInitialMount.current = false; | |
| } else { | |
| return effect(); | |
| } | |
| }, dependencies); | |
| } | |
| // useFetch | |
| interface FetchState<T> { | |
| data: T | null; | |
| error: Error | null; | |
| loading: boolean; | |
| } | |
| function useFetch<T>(url: string, options?: RequestInit): FetchState<T> { | |
| const [state, setState] = useState<FetchState<T>>({ data: null, error: null, loading: true }); | |
| useEffect(() => { | |
| setState({ data: null, error: null, loading: true }); | |
| fetch(url, options) | |
| .then(response => response.json()) | |
| .then(data => setState({ data, error: null, loading: false })) | |
| .catch(error => setState({ data: null, error, loading: false })); | |
| }, [url, options]); | |
| return state; | |
| } | |
| // useTimeout | |
| function useTimeout(callback: () => void, delay: number | null) { | |
| const callbackRef = useRef(callback); | |
| useEffect(() => { | |
| callbackRef.current = callback; | |
| }, [callback]); | |
| useEffect(() => { | |
| if (delay !== null) { | |
| const id = setTimeout(() => callbackRef.current(), delay); | |
| return () => clearTimeout(id); | |
| } | |
| }, [delay]); | |
| // Optionally return a function to clear the timeout | |
| } | |
| export { | |
| useAsync, | |
| useDebounce, | |
| useEventListener, | |
| useLocalStorage, | |
| useMediaQuery, | |
| useOnClickOutside, | |
| usePrevious, | |
| useToggle, | |
| useUpdateEffect, | |
| useFetch, | |
| useTimeout, | |
| }; |
interface Observable<T> {
/**
* @deprecated
*/
// @ts-ignore
map: typeof null;
/**
* @deprecated
*/
// @ts-ignore
filter: typeof null;
/**
* @deprecated
*/
// @ts-ignore
reduce: typeof null;
/**
* @deprecated
*/
// @ts-ignore
scan: typeof null;
/**
* @deprecated
*/
// @ts-ignore
mergeMap: typeof null;
/**
* @deprecated
*/
// @ts-ignore
switchMap: typeof null;
/**
* @deprecated
*/
// @ts-ignore
concatMap: typeof null;
/**
* @deprecated
*/
// @ts-ignore
exhaustMap: typeof null;
/**
* @deprecated
*/
// @ts-ignore
take: typeof null;
/**
* @deprecated
*/
// @ts-ignore
first: typeof null;
/**
* @deprecated
*/
// @ts-ignore
last: typeof null;
/**
* @deprecated
*/
// @ts-ignore
skip: typeof null;
/**
* @deprecated
*/
// @ts-ignore
debounce: typeof null;
/**
* @deprecated
*/
// @ts-ignore
throttle: typeof null;
/**
* @deprecated
*/
// @ts-ignore
catchError: typeof null;
/**
* @deprecated
*/
// @ts-ignore
finalize: typeof null;
/**
* @deprecated
*/
// @ts-ignore
tap: typeof null;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
interface Observable {
/**
*/
// @ts-ignore
map: typeof null;
/**
*/
// @ts-ignore
filter: typeof null;
/**
*/
// @ts-ignore
reduce: typeof null;
/**
*/
// @ts-ignore
scan: typeof null;
/**
*/
// @ts-ignore
mergeMap: typeof null;
/**
*/
// @ts-ignore
switchMap: typeof null;
/**
*/
// @ts-ignore
concatMap: typeof null;
/**
*/
// @ts-ignore
exhaustMap: typeof null;
/**
*/
// @ts-ignore
take: typeof null;
/**
*/
// @ts-ignore
first: typeof null;
/**
*/
// @ts-ignore
last: typeof null;
/**
*/
// @ts-ignore
skip: typeof null;
/**
*/
// @ts-ignore
debounce: typeof null;
/**
*/
// @ts-ignore
throttle: typeof null;
/**
*/
// @ts-ignore
catchError: typeof null;
/**
*/
// @ts-ignore
finalize: typeof null;
/**
*/
// @ts-ignore
tap: typeof null;
}