diff --git a/.changeset/soft-radios-attend.md b/.changeset/soft-radios-attend.md new file mode 100644 index 0000000..46c8838 --- /dev/null +++ b/.changeset/soft-radios-attend.md @@ -0,0 +1,5 @@ +--- +"@nf-team/react": minor +--- + +feat(useUnmount): useUnmount hook 구현 및 적용 diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index 4cc8cc7..01dcb70 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -9,4 +9,5 @@ export { default as useLessThenScrollY } from './useLessThenScrollY'; export { default as useResizeViewportHeight } from './useResizeViewportHeight'; export { default as useThrottleCallback } from './useThrottleCallback'; export { default as useTimeout } from './useTimeout'; +export { default as useUnmount } from './useUnmount'; export { default as useUpdateEffect } from './useUpdateEffect'; diff --git a/packages/react/src/hooks/useUnmount.test.ts b/packages/react/src/hooks/useUnmount.test.ts new file mode 100644 index 0000000..189f3f6 --- /dev/null +++ b/packages/react/src/hooks/useUnmount.test.ts @@ -0,0 +1,23 @@ +import { act, renderHook } from '@testing-library/react'; + +import useUnmount from './useUnmount'; + +describe('useUnmount', () => { + const effectCallback = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + const useUnmountHook = () => renderHook(() => useUnmount(effectCallback)); + + it('unmount되면 콜백함수가 호출되어야만 한다', () => { + const { unmount } = useUnmountHook(); + + act(() => { + unmount(); + }); + + expect(effectCallback).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/react/src/hooks/useUnmount.ts b/packages/react/src/hooks/useUnmount.ts new file mode 100644 index 0000000..6c8d4cc --- /dev/null +++ b/packages/react/src/hooks/useUnmount.ts @@ -0,0 +1,14 @@ +import { useRef } from 'react'; + +import useEffectOnce from './useEffectOnce'; + +function useUnmount(fn: () => void) { + const fnRef = useRef(fn); + + // NOTE - ref 각 렌더를 업데이트하여 변경하면 최신 콜백이 실행 + fnRef.current = fn; + + useEffectOnce(() => () => fnRef.current()); +} + +export default useUnmount;