Skip to content

Commit

Permalink
fix(#792): make useUnmount invoke the current callback version instea…
Browse files Browse the repository at this point in the history
…d of very first
  • Loading branch information
xobotyi committed Nov 22, 2019
1 parent f8dd075 commit 75284c6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 21 deletions.
10 changes: 8 additions & 2 deletions src/useUnmount.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { useRef } from 'react';
import useEffectOnce from './useEffectOnce';

const useUnmount = (fn: () => void | undefined) => {
useEffectOnce(() => fn);
const useUnmount = (fn: () => any): void => {
const fnRef = useRef(fn);

// update the ref each render so if it change the newest callback will be invoked
fnRef.current = fn;

useEffectOnce(() => () => fnRef.current());

This comment has been minimized.

Copy link
@yqrashawn

yqrashawn Dec 16, 2022

@xobotyi just curious
Is there particular reason/thoughts behind this
Why not useEffectOnce(() => fnRef.current);
Is it for getting an error if current is not a function when unmount?

};

export default useUnmount;
57 changes: 38 additions & 19 deletions tests/useUnmount.test.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,51 @@
import { renderHook } from '@testing-library/react-hooks';
import { useUnmount } from '../src';

const mockCallback = jest.fn();
describe('useUnmount', () => {
it('should be defined', () => {
expect(useUnmount).toBeDefined();
});

afterEach(() => {
jest.resetAllMocks();
});
it('should not call provided callback on mount', () => {
const spy = jest.fn();
renderHook(() => useUnmount(spy));

it('should not call provided callback on mount', () => {
renderHook(() => useUnmount(mockCallback));
expect(spy).not.toHaveBeenCalled();
});

expect(mockCallback).not.toHaveBeenCalled();
});
it('should not call provided callback on re-renders', () => {
const spy = jest.fn();
const hook = renderHook(() => useUnmount(spy));

it('should call provided callback on unmount', () => {
const { unmount } = renderHook(() => useUnmount(mockCallback));
expect(mockCallback).not.toHaveBeenCalled();
hook.rerender();
hook.rerender();
hook.rerender();
hook.rerender();

unmount();
expect(spy).not.toHaveBeenCalled();
});

expect(mockCallback).toHaveBeenCalledTimes(1);
});
it('should call provided callback on unmount', () => {
const spy = jest.fn();
const hook = renderHook(() => useUnmount(spy));

hook.unmount();

expect(spy).toHaveBeenCalledTimes(1);
});

it('should not call provided callback on rerender', () => {
const { rerender } = renderHook(() => useUnmount(mockCallback));
expect(mockCallback).not.toHaveBeenCalled();
it('should call provided callback if is has been changed', () => {
const spy = jest.fn();
const spy2 = jest.fn();
const spy3 = jest.fn();
const hook = renderHook(cb => useUnmount(cb), { initialProps: spy });

rerender();
hook.rerender(spy2);
hook.rerender(spy3);
hook.unmount();

expect(mockCallback).not.toHaveBeenCalled();
expect(spy).not.toHaveBeenCalled();
expect(spy2).not.toHaveBeenCalled();
expect(spy3).toHaveBeenCalledTimes(1);
});
});

0 comments on commit 75284c6

Please sign in to comment.