Skip to content

Commit

Permalink
feat: Add useUnmount hook
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasEng committed Jan 9, 2025
1 parent a712b7d commit 6972431
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions frontend/libs/studio-hooks/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './useDebounce';
export * from './useForwardedRef';
export * from './usePropState';
export * from './useUniqueKeys';
export * from './useUnmount';
46 changes: 46 additions & 0 deletions frontend/libs/studio-hooks/src/hooks/useUnmount.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { RenderHookResult } from '@testing-library/react';
import { renderHook } from '@testing-library/react';
import { useUnmount } from './useUnmount';

describe('useUnmount', () => {
it('Does not call the function on first render', () => {
const fun = jest.fn();
renderUseUnmount(fun);
expect(fun).not.toHaveBeenCalled();
});

it('Does not call the function on rerender', () => {
const fun = jest.fn();
const { rerender } = renderUseUnmount(fun);
rerender({ fun });
expect(fun).not.toHaveBeenCalled();
});

it('Calls the function on unmount', () => {
const fun = jest.fn();
const { unmount } = renderUseUnmount(fun);
unmount();
expect(fun).toHaveBeenCalledTimes(1);
});

it('Calls the most recent function on unmount when it has rendered with different functions', () => {
const firstFun = jest.fn();
const secondFun = jest.fn();
const { rerender, unmount } = renderUseUnmount(firstFun);
rerender({ fun: secondFun });
unmount();
expect(firstFun).not.toHaveBeenCalled();
expect(secondFun).toHaveBeenCalledTimes(1);
});
});

type RenderUseUnmountProps = {
fun: () => void;
};

function renderUseUnmount(fun: () => void): RenderHookResult<void, RenderUseUnmountProps> {
const props: RenderUseUnmountProps = { fun };
return renderHook<void, RenderUseUnmountProps>((props) => useUnmount(props.fun), {
initialProps: props,
});
}
11 changes: 11 additions & 0 deletions frontend/libs/studio-hooks/src/hooks/useUnmount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useEffect, useRef } from 'react';

export function useUnmount(fun: () => void): void {
const functionRef = useRef<() => void>(fun);

useEffect(() => {
functionRef.current = fun;
}, [fun]);

useEffect(() => () => functionRef.current(), []);
}

0 comments on commit 6972431

Please sign in to comment.