Skip to content

Commit

Permalink
Prevent useBeforeMount to invoke twice after change in useIsMounted
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaNarie committed Apr 4, 2023
1 parent c2475c2 commit a5b7da0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
22 changes: 21 additions & 1 deletion src/hooks/useBeforeMount/useBeforeMount.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { jest } from '@jest/globals';
import { renderHook } from '@testing-library/react';
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useMount } from '../useMount/useMount.js';
import { useBeforeMount } from './useBeforeMount.js';

describe('useBeforeMount', () => {
Expand Down Expand Up @@ -59,4 +60,23 @@ describe('useBeforeMount', () => {
rerender();
expect(spy).toBeCalledTimes(1);
});

it('should only execute once when setState is called during useMount', async () => {
const spy = jest.fn();
const { rerender } = renderHook(() => {
// eslint-disable-next-line react/hook-use-state
const [, setState] = useState(false);

useBeforeMount(spy);

useMount(() => {
setState(true);
});
});
expect(spy).toBeCalledTimes(1);

await Promise.resolve();
rerender();
expect(spy).toBeCalledTimes(1);
});
});
12 changes: 9 additions & 3 deletions src/hooks/useBeforeMount/useBeforeMount.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useIsMounted } from '../useIsMounted/useIsMounted.js';
import { useRef } from 'react';
import { useMount } from '../useMount/useMount.js';

/**
* Executes a callback during the initial render, before mounting, but not during subsequent
Expand All @@ -11,8 +12,13 @@ import { useIsMounted } from '../useIsMounted/useIsMounted.js';
* during subsequent renders.
*/
export function useBeforeMount(callback: () => void): void {
const isMounted = useIsMounted();
if (!isMounted.current) {
const isBeforeMount = useRef(true);

if (isBeforeMount.current) {
callback();
}

useMount(() => {
isBeforeMount.current = false;
});
}

0 comments on commit a5b7da0

Please sign in to comment.