@kmpizmad/react-hooks-util
v1.0.0
Published
Utility library for common React hooks such as useMountEffect, useUpdateEffect, useUnmount effect etc..
Downloads
2
Maintainers
Readme
Introduction
Utility library for common React hooks
The idea was to create a library that contains common functionalities abstracted into hooks rather than implementing them everytime in every project.
Guidelines
- Checkout the latest updates in the changelog
- See our contributing guidelines
- See our Support Guide
- See our Security Policy
Lifecycle hooks
useMountEffect
type: (effect: React.EffectCallback) => void
Represents the componentDidMount
method from React class components
const DidMountComponent = () => {
const [value, setValue] = React.useState<number>(0);
const [dependency, setDependency] = React.useState<number>(0);
useMountEffect(() => {
setValue(dependency + 1);
});
return (
<div>
<div data-testid="test-value">{value}</div>
<button onClick={() => setDependency(dependency + 1)}>Click Me!</button>
</div>
);
};
useUnmountEffect
type: (effect: React.EffectCallback, deps: React.DependencyList = []) => void
Represents the componentWillUnmount
method from React class components
const WillUnmountComponent = () => {
const [value, setValue] = React.useState<number>(0);
useUnmountEffect(() => {
setValue(-1);
});
return <div>{value}</div>;
};
useUpdateEffect
type: (effect: React.EffectCallback, deps?: React.DependencyList) => void
Renders whenever a dependency changes or if provided without a dependency list, renders on any change. Avoid providing an empty dependency list
const DidUpdateComponent = () => {
const [value, setValue] = React.useState<number>(0);
const [dependency, setDependency] = React.useState<number>(0);
useUpdateEffect(() => {
setValue(dependency);
}, [dependency]);
return (
<div>
<div>{value}</div>
<button onClick={() => setDependency(dependency + 1)}>Click Me!</button>
</div>
);
};
usePrevState
type: (state: PrevState) => PrevState
getSnapshotBeforeUpdate
, componentShouldUpdate
and componentWillRecieveProps
combined in one. Captures the previous state based on the input object
const PrevStateComponent = () => {
const [dependency, setDependency] = React.useState<number>(0);
const prevState = usePrevState({ dependency });
return (
<div>
<div>{prevState?.dependency || '-1'}</div>
<button onClick={() => setDependency(dependency + 1)}>Click Me!</button>
</div>
);
};
DOM hooks
useToggle
type: (initialValue?: boolean) => ToggleObject
Toggles state between true
and false
const ToggleComponent = (props: { initialValue?: boolean }) => {
const { value, toggle } = useToggle(props.initialValue);
return (
<div>
<div>{value.toString()}</div>
<button onClick={() => toggle()}>Click Me!</button>
</div>
);
};
useEventListener
type: (type: keyof WindowEventMap, callback: (event: Event) => void, element: HTMLElement | Document | (Window & typeof globalThis) = window) => void
Attaches a global event listener to the element
(window
object by default).
const EventListenerComponent = () => {
const [value, setValue] = React.useState('Loading');
useEventListener('load', () => {
setTimeout(() => {
setValue('Hello World!');
}, 100);
});
return <div data-testid="test-value">{value}</div>;
};
useScript
type: (url: string) => AsyncObjectWithoutData
Loads in a script and adds a new script
node to the DOM.
const ScriptComponent = () => {
const { loading, error } = useScript(
'https://code.jquery.com/jquery-3.6.0.min.js'
);
if (loading) return <div>Loading</div>;
if (error) return <div>Error</div>;
return (
<div>
{Object.keys(window)
.includes('$')
.toString()}
</div>
);
};
Util hooks
useTimeout
type: (callback: () => void, ms: number) => TimeoutObject
Basically setTimeout
as a hook.
const TimeoutComponent = () => {
const [count, setCount] = React.useState(10);
const { clear, reset } = useTimeout(() => setCount(0), 1000);
return (
<div>
<div>{count}</div>
<button onClick={clear}>Clear</button>
<button onClick={reset}>Reset</button>
</div>
);
};
useDebounce
type: (callback: () => void, ms: number, deps: React.DependencyList = []) => void
const DebounceComponent = () => {
const [count, setCount] = React.useState(0);
const [dependency, setDependency] = React.useState(10);
useDebounce(() => setCount(dependency), 200, [dependency]);
return (
<div>
<div>{count}</div>
<button onClick={() => setDependency(dependency + 1)}>Click Me!</button>
</div>
);
};
useTextShortener
type: (text: string, options: TextShortenerOptions) => string
Shortens a text to a specified limit
. Customizable through options
.
const TextShortenerComponent = (props: Omit<TextShortenerOptions, 'limit'>) => {
const [limit, setLimit] = React.useState(11);
const short = useTextShortener('Lorem ipsum dolor sit amet', {
limit,
...props,
});
return (
<div>
<div>{short}</div>
<button onClick={() => setLimit(6)}>Click Me!</button>
</div>
);
};
useOnlineStatus
type: () => boolean
Returns true
or false
. Depends on the browser agent status.
useRenderCount
type: () => number
useDebugInfo
type: <Props extends Record<string, any>>(Component: React.ComponentType<Props>, props: Record<string, any>) => DebugInfo
const DebugComponent: React.FC<{ count: number }> = props => {
const [count, setCount] = React.useState(props.count);
const debug = useDebugInfo(DebugComponent, { count });
return (
<div>
<div>{JSON.stringify(debug)}</div>
<button onClick={() => setCount(count + 1)}>Click Me!</button>
</div>
);
};
useLocalStorage
type: (key: string, defaultValue: Value) => StorageObject
Handles and stores data in window.localStorage
const LocalStorageComponent = () => {
const { value, update, remove } = useLocalStorage('test', 'Hello World!');
return (
<div>
<div>{value}</div>
<button onClick={() => update('Hi')}>Update</button>
<button onClick={() => remove()}>Remove</button>
</div>
);
};
useSessionStorage
type: (key: string, defaultValue: Value) => StorageObject
Handles and stores data in window.sessionStorage
const SessionStorageComponent = () => {
const { value, update, remove } = useSessionStorage('test', 'Hello World!');
return (
<div>
<div>{value}</div>
<button onClick={() => update('Hi')}>Update</button>
<button onClick={() => remove()}>Remove</button>
</div>
);
};
Asynchronous hooks
useAsync
type: <T = any>(promise: () => Promise<T>, deps: React.DependencyList = []) => AsyncObject<T>
Handles async functions, re-evaluates whenever a dependency changes
const AsyncComponent = (props: { success?: boolean }) => {
const { loading, error, data } = useAsync<string>(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
props.success ? resolve('Hello World!') : reject({ message: 'Error' });
}, 1000);
});
});
return (
<div>
<div>{loading.toString()}</div>
{error && <div>{JSON.stringify(error)}</div>}
{data && <div>{data}</div>}
</div>
);
};
useFetch
type: <T = any>(config: FetchConfig, deps: React.DependencyList = []) => AsyncObject<T>
Handles API requests, uses the built-in fetch
module
Types
AsyncObject
{
loading: boolean;
error: AsyncError | undefined;
data: T | undefined;
}
AsyncError
{
message: string;
[key: number | string]: any;
}
DebugInfo
{
renderCount: number;
changedProps: Record<string, any>;
timeSinceLastRender: number;
lastRenderTimestamp: number;
}
FetchConfig
{
url: string;
options?: RequestInit
};
State
{
[key: number | string]: any
};
StorageObject
{
value: Value;
update: (value: Value) => void;
remove: () => void;
}
TimeoutObject
{
reset: () => void;
clear: () => void;
}
ToggleObject
{
value: boolean;
toggle: () => void
}
Value
string | number | boolean | Record<string, any> | null | undefined