Skip to content

Instantly share code, notes, and snippets.

@itproto
Created February 29, 2024 01:07
Show Gist options
  • Save itproto/d2d5624e42c9bc40916990b81502cae4 to your computer and use it in GitHub Desktop.
Save itproto/d2d5624e42c9bc40916990b81502cae4 to your computer and use it in GitHub Desktop.
AXIS.md
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,
};
@itproto
Copy link
Author

itproto commented Apr 2, 2024

interface Observable {
/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

/**

@itproto
Copy link
Author

itproto commented Apr 2, 2024


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