Skip to content

Commit

Permalink
feat(hooks): add after mount effects hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
dackmin committed Dec 15, 2022
1 parent 734402b commit 9735822
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 6 deletions.
1 change: 1 addition & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module.exports = {
config.resolve.alias = {
'react-native': 'react-native-web',
'@junipero/core': path.resolve('./packages/core/lib'),
'@junipero/react': path.resolve('./packages/react/lib'),
'@junipero/hooks': path.resolve('./packages/hooks/lib'),
'@junipero/transitions': path.resolve('./packages/transitions/lib'),
};
Expand Down
30 changes: 25 additions & 5 deletions packages/hooks/lib/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef, useEffect } from 'react';
import { useRef, useEffect, useLayoutEffect } from 'react';

export const useEventListener = (
name,
Expand Down Expand Up @@ -28,11 +28,11 @@ export const useEventListener = (
};

export const useInterval = (
cb, time, changes = [], { enabled = true } = {}
cb, time, changes = [], { enabled = true, layoutEffect = false } = {}
) => {
const returnedCallbackRef = useRef();

useEffect(() => {
(layoutEffect ? useLayoutEffect : useEffect)(() => {
if (!enabled) {
return;
}
Expand All @@ -49,11 +49,11 @@ export const useInterval = (
};

export const useTimeout = (
cb, time, changes = [], { enabled = true } = {}
cb, time, changes = [], { enabled = true, layoutEffect = false } = {}
) => {
const returnedCallbackRef = useRef();

useEffect(() => {
(layoutEffect ? useLayoutEffect : useEffect)(() => {
if (!enabled) {
return;
}
Expand All @@ -68,3 +68,23 @@ export const useTimeout = (
};
}, changes);
};

const useAfterMount = (cb, changes = [], { layoutEffect = false } = {}) => {
const mounted = useRef(false);

(layoutEffect ? useLayoutEffect : useEffect)(() => {
if (!mounted.current) {
mounted.current = true;

return;
}

return cb();
}, changes);
};

export const useEffectAfterMount = (cb, changes = []) =>
useAfterMount(cb, changes);

export const useLayoutEffectAfterMount = (cb, changes = []) =>
useAfterMount(cb, changes, { layoutEffect: true });
48 changes: 47 additions & 1 deletion packages/hooks/lib/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import { useState } from 'react';
import { render, fireEvent } from '@testing-library/react';
import { classNames } from '@junipero/core';

import { useEventListener, useTimeout, useInterval } from './';
import {
useEventListener,
useTimeout,
useInterval,
useEffectAfterMount,
useLayoutEffectAfterMount,
} from './';

/* eslint-disable react/prop-types */
const TestComponent = ({ target, onTimeout, onInterval }) => {
Expand Down Expand Up @@ -64,3 +70,43 @@ describe('useTimeout(listener, time, changes)', () => {
jest.useRealTimers();
});
});

/* eslint-disable react/prop-types */
const EffectsTestComponent = ({ enabled, onEffect, onLayoutEffect }) => {
onEffect && useEffectAfterMount(() => {
onEffect();
}, [enabled]);

onLayoutEffect && useLayoutEffectAfterMount(() => {
onLayoutEffect();
}, [enabled]);

return null;
};
/* eslint-enable react/prop-types */

describe('useEffectAfterMount(cb, changes)', () => {
it('should execute task after mount', () => {
const onEffect = jest.fn();
const { unmount, rerender } = render(
<EffectsTestComponent enabled={false} onEffect={onEffect} />
);
rerender(<EffectsTestComponent enabled={true} onEffect={onEffect} />);
expect(onEffect).toHaveBeenCalledTimes(1);
unmount();
});
});

describe('useLayoutEffectAfterMount(cb, changes)', () => {
it('should execute task after mount', () => {
const onLayoutEffect = jest.fn();
const { unmount, rerender } = render(
<EffectsTestComponent enabled={false} onLayoutEffect={onLayoutEffect} />
);
rerender(
<EffectsTestComponent enabled={true} onLayoutEffect={onLayoutEffect} />
);
expect(onLayoutEffect).toHaveBeenCalledTimes(1);
unmount();
});
});

0 comments on commit 9735822

Please sign in to comment.