The @drpiou/react-utils
package provides some React utilities.
- written in TypeScript.
- React (17.0.2+)
- React Native (0.64.0+)
- Expo (43+)
yarn add @drpiou/react-utils
The withHooks
React HOC wraps the React Class component with React hooks.
import {
useIsMounted,
useOnMount,
useOnUnmount,
withHooks,
WithHooksProps,
} from '@drpiou/react-utils';
type Props = WithHooksProps<
{
useIsMounted: typeof useIsMounted;
useOnMount: typeof useOnMount;
useOnUnmount: typeof useOnUnmount;
},
HTMLProps<HTMLParagraphElement>
>;
type State = {
state: boolean;
};
class MyComponent extends Component<Props, State> {
_handleClick = this.handleClick.bind(this);
state: State = {
state: false,
};
handleClick(): void {
const { useIsMounted: hookIsMounted } = this.props;
setTimeout(() => {
if (hookIsMounted.current) {
this.setState((prevState) => ({ state: !prevState.state }));
}
}, 3000);
}
render(): JSX.Element {
const { state } = this.state;
return (
<div className={'card'}>
<button
onClick={this._handleClick}
>{`click to change state in 3s (withHooks+useIsMounted: ${String(
state,
)})`}</button>
</div>
);
}
}
const MyComponentWithHooks = withHooks({
useIsMounted,
useOnMount: [
useOnMount,
[
(): void => {
console.log('mounted');
},
],
],
useOnUnmount: [
useOnUnmount,
(props: unknown): Parameters<typeof useOnMount> => [
(): void => {
console.log('unmounted', { props });
},
],
],
})(MyComponent);
The useCallbackEvent
React hook will return a memoized version of the callback that is internally linked to a reference.
This is an implementation attempt of the useEvent
React hook.
import { useCallbackEvent } from '@drpiou/react-utils';
const MyComponent = (): JSX.Element => {
const [state, setState] = React.useState<boolean>(false);
const handleClick = useCallbackEvent((): void => {
setState(!state);
});
return <div onClick={handleClick} />;
};
The useIsMounted
React hook provides the mounted state of the component.
import { useIsMounted } from '@drpiou/react-utils';
const MyComponent = (): JSX.Element => {
const isMounted = useIsMounted();
const [state, setState] = React.useState<boolean>(false);
const handleClick = (): void => {
if (isMounted.current) {
setState((prevState) => !prevState);
}
};
return <div onClick={handleClick} />;
};
The useOnMount
React hook execute a callback once when the component is mounted.
import { useOnMount } from '@drpiou/react-utils';
const MyComponent = (): JSX.Element => {
useOnMount(() => {
console.log('Mounted');
});
return <></>;
};
The useOnUnmount
React hook execute a callback once when the component is unmounted.
import { useOnUnmount } from '@drpiou/react-utils';
const MyComponent = (): JSX.Element => {
useOnUnmount(() => {
console.log('Unmounted');
});
return <></>;
};
The useStateSafe
React hook prevents the useState
React hook to execute if the component is unmounted.
import { useStateSafe } from '@drpiou/react-utils';
const MyComponent = (): JSX.Element => {
const [state, setState] = useStateSafe<boolean>(false);
const handleClick = (): void => {
setState((prevState) => !prevState);
};
return <div onClick={handleClick} />;
};
The useTimeout
React hook wraps the setTimeout
and clearTimeout
functions.
It clears automatically the timeout when the component is unmounted.
import { useTimeout } from '@drpiou/react-utils';
const MyComponent = (): JSX.Element => {
const [state, setState] = React.useState<boolean>(false);
const timeout = useTimeout();
const handleClick = (): void => {
timeout.set(() => {
setState((prevState) => !prevState);
}, 1000);
};
return <div onClick={handleClick} />;
};
The getComponentName
utility returns the component name or undefined.
It clears automatically the timeout when the component is unmounted.
import { getComponentName } from '@drpiou/react-utils';
const result = getComponentName(MyComponent);
// => 'MyComponent'