Skip to content

Instantly share code, notes, and snippets.

View davemecha's full-sized avatar

Dave Gööck davemecha

  • Gööck UG (haftungsbeschränkt)
  • Magdeburg
View GitHub Profile
@davemecha
davemecha / DebouncedTextField.tsx
Created January 6, 2022 19:20
A debounced Material UI TextField component
import { TextField, TextFieldProps } from '@material-ui/core';
import { ChangeEvent, memo, useCallback, useEffect, useRef, useState } from 'react';
function DebouncedTextField({ value, onChange, timeout = 1000, ...props }: TextFieldProps & { timeout?: number }) {
const timeoutHandlerRef = useRef<ReturnType<typeof setTimeout>>();
const [currentValue, setCurrentValue] = useState(value);
const handleChange = useCallback((event: ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
const value = event.target.value;
setCurrentValue(value);
@davemecha
davemecha / useDebounceEffect.ts
Created January 6, 2022 19:06
Hook for a react effect that is debounced.
// inspired by https://github.com/bellawatt/use-debounce-effect
import { DependencyList, useEffect, useRef } from 'react'
export default function useDebounceEffect(cb: () => void, delay: number, values: DependencyList, runOnInit = false) {
const didMountRef = useRef<boolean>(false);
useEffect(() => {
if (!runOnInit && !didMountRef.current) {
didMountRef.current = true;
@davemecha
davemecha / useDeepCompareMemoize.ts
Created October 25, 2021 13:36
Helper hook to memoize params for deep comparison in useEffect
import { isEqual } from 'lodash';
import { useRef } from 'react';
/**
* usage:
* `useEffect(() => { ... }, [useDeepCompareMemoize(param)]);`
*/
export default function useDeepCompareMemoize<T>(value: T) {
const ref = useRef<T>();
@davemecha
davemecha / useDebouncedSelector.ts
Last active October 9, 2023 07:03
Typed debounced selector for react-redux
import { useEffect, useRef, useState } from 'react';
import { TypedUseSelectorHook, useSelector } from 'react-redux';
// S is the RootState. If used with reselect, it can be derived. Otherwise, it could also initialized here with S = RootState
export function useDebouncedSelector<T, S>(selector: (state: S) => T, time = 100, equalityFn?: (left: T, right: T) => boolean) {
const useAppSelector: TypedUseSelectorHook<S> = useSelector;
const [state, setState] = useState<{ data: T | undefined }>({ data: undefined });
const result = useRef<T>();
const data = useAppSelector<T>(selector, equalityFn);
@davemecha
davemecha / mapObject.ts
Last active October 18, 2021 13:26
Typed mapping of a tapescript object to a new object with same keys
type ValueOf<T> = T[keyof T];
// Since I find the typing in record not as convenient I return an object type.
// The record type could be returned as well. Just omit the return type definition.
export function mapObject<IN extends Record<string, unknown>, VAL>(
map: (v: ValueOf<IN>, k: keyof IN) => VAL,
obj: IN,
): { [K in keyof IN]: VAL } {
const result = {} as Record<keyof IN, VAL>;
for (const i in obj) {
@davemecha
davemecha / fromEntries.ts
Created October 18, 2021 13:00
Typed replacement for Object.fromEntries
export function fromEntries<K extends string, V>(entries: [K, V][]) {
return Object.fromEntries(entries) as {
[key in K]: V
};
}
@davemecha
davemecha / fixLoopFilter.js
Last active June 7, 2016 13:19
Filter as a workaround for a $digest loop problem with angular-meteor in custom filters.
/*******************************************************************************
* @author: Dave Gööck<dave@goeoeck.net>
*
* This small filter is just a workaround for some problem with angular-meteor.
*
* It doesn't really filter any element of the input array but returns a clone
* of the input. The clone is the same instance for each input configuration.
* It's not a deep clone. If the input array contains objects, the result array
* will contain the same instances.
*