Last active
April 5, 2025 18:08
-
-
Save brandonscript/34ef9d47b513439511b464e50917c17a to your computer and use it in GitHub Desktop.
A debounced TextField component for React + MaterialUI
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 { TextField, type TextFieldProps } from "@mui/material"; | |
import { forwardRef, useImperativeHandle, useState } from "react"; | |
import { type Options as UseDebouncedCallbackOptions, useDebouncedCallback } from "use-debounce"; | |
export type DebouncedTextFieldRef = { | |
cancelDebounce?: () => void; | |
clear: () => void; | |
}; | |
type DebouncedTextFieldProps = TextFieldProps & { | |
debounceTime?: number; | |
debounceOptions?: UseDebouncedCallbackOptions; | |
}; | |
export const DebouncedTextField = forwardRef<DebouncedTextFieldRef, DebouncedTextFieldProps>( | |
({ value, onChange = () => {}, debounceTime, debounceOptions, ...props }, ref) => { | |
const [localValue, setLocalValue] = useState(value); | |
const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => { | |
setLocalValue(e.target.value); | |
debouncedOnChange(e); | |
}; | |
const debouncedOnChange = useDebouncedCallback<typeof handleOnChange>( | |
onChange, | |
debounceTime ?? 500, | |
debounceOptions, | |
); | |
useImperativeHandle(ref, () => ({ | |
cancelDebounce: debouncedOnChange.cancel, | |
clear: () => { | |
setLocalValue(""); | |
debouncedOnChange.cancel(); | |
}, | |
})); | |
useEffect(() => { | |
if (value !== localValue) { | |
setLocalValue(value); | |
} | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, [value]); | |
return <TextField value={localValue} onChange={handleOnChange} {...props} />; | |
}, | |
); | |
DebouncedTextField.displayName = "DebouncedTextField"; |
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 } from "react"; | |
import { type Options as UseDebouncedCallbackOptions, useDebounce, useDebouncedCallback } from "use-debounce"; | |
export const useDebouncedSetState = <T>( | |
initialState: T, | |
debounceTime?: number, | |
debounceOptions?: UseDebouncedCallbackOptions, | |
) => { | |
const [state, setState] = useState<T>(initialState); | |
const debouncedSetState = useDebouncedCallback(setState, debounceTime, debounceOptions); | |
return [state, debouncedSetState] as const; | |
}; | |
export const useDebouncedState = <T>(initialState: T, delay: number, debounceOptions?: UseDebouncedCallbackOptions) => { | |
const [state, setState] = useState<T>(initialState); | |
const [debouncedState, debounce] = useDebounce(state, delay, debounceOptions); | |
return [debouncedState, setState, debounce] as const; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment