Skip to content

Commit

Permalink
feat: remove additional hooks library (#252)
Browse files Browse the repository at this point in the history
- remove usehooks-ts

- partial prep for move to react 19
  • Loading branch information
thenick775 authored Jan 26, 2025
1 parent daadf78 commit 81127d3
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 7 deletions.
3 changes: 1 addition & 2 deletions gbajs3/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions gbajs3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@
"react-modal": "^3.16.1",
"react-rnd": "^10.4.1",
"react-spinners": "^0.15.0",
"styled-components": "^6.1.1",
"usehooks-ts": "^3.0.1"
"styled-components": "^6.1.1"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.1.6",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useLocalStorage } from '@uidotdev/usehooks';
import { useState } from 'react';
import Joyride, { STATUS, type Step } from 'react-joyride';
import { useInterval } from 'usehooks-ts';

import { productTourLocalStorageKey } from './consts.tsx';
import { useModalContext } from '../../hooks/context.tsx';
import { useInterval } from '../../hooks/use-interval.ts';

import type { CompletedProductTourSteps } from './product-tour-intro.tsx';

Expand Down
3 changes: 2 additions & 1 deletion gbajs3/src/components/shared/circle-check-button.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Button } from '@mui/material';
import { useId, useState } from 'react';
import { styled, keyframes } from 'styled-components';
import { useInterval } from 'usehooks-ts';

import { useInterval } from '../../hooks/use-interval.ts';

import type { ButtonProps } from '@mui/material';

Expand Down
2 changes: 1 addition & 1 deletion gbajs3/src/context/auth/auth-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { jwtDecode, type JwtPayload } from 'jwt-decode';
import { useState, useEffect, useCallback, type ReactNode } from 'react';
import { useInterval } from 'usehooks-ts';

import {
AuthContext,
type AuthContextProps,
type AccessTokenSource
} from './auth-context.tsx';
import { useInterval } from '../../hooks/use-interval.ts';
import { useRefreshAccessToken } from '../../hooks/use-refresh.tsx';

type AuthProviderProps = { children: ReactNode };
Expand Down
133 changes: 133 additions & 0 deletions gbajs3/src/hooks/use-interval.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { renderHook, act } from '@testing-library/react';
import { vi, describe, it, expect, beforeEach } from 'vitest';

import { useInterval } from './use-interval.ts';

describe('useInterval', () => {
beforeEach(() => {
vi.useFakeTimers();
});

it('should call the callback at the specified interval', () => {
const callback = vi.fn();

renderHook(() => useInterval(callback, 1000));

act(() => {
vi.advanceTimersByTime(3000);
});

expect(callback).toHaveBeenCalledTimes(3);
});

it('should not call the callback if delay is null', () => {
const callback = vi.fn();

renderHook(() => useInterval(callback, null));

act(() => {
vi.advanceTimersByTime(1000);
});

expect(callback).not.toHaveBeenCalled();
});

it('should not call the callback after unmounting', () => {
const callback = vi.fn();

const { unmount } = renderHook(() => useInterval(callback, 1000));

act(() => {
vi.advanceTimersByTime(1000);
});

expect(callback).toHaveBeenCalledTimes(1);

unmount();

act(() => {
vi.advanceTimersByTime(1000);
});

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

it('should update the callback without resetting the interval', () => {
const initialCallback = vi.fn();
const updatedCallback = vi.fn();

const { rerender } = renderHook(
({ callback }) => useInterval(callback, 1000),
{
initialProps: { callback: initialCallback }
}
);

act(() => {
vi.advanceTimersByTime(1000);
});

expect(initialCallback).toHaveBeenCalledTimes(1);
expect(updatedCallback).not.toHaveBeenCalled();

rerender({ callback: updatedCallback });

act(() => {
vi.advanceTimersByTime(1000);
});

expect(initialCallback).toHaveBeenCalledTimes(1);
expect(updatedCallback).toHaveBeenCalledTimes(1);
});

it('should update the interval when delay changes', () => {
const callback = vi.fn();

const { rerender } = renderHook(
({ delay }) => useInterval(callback, delay),
{
initialProps: { delay: 1000 }
}
);

act(() => {
vi.advanceTimersByTime(1000);
});

expect(callback).toHaveBeenCalledTimes(1);

rerender({ delay: 200 });

act(() => {
vi.advanceTimersByTime(500);
});

expect(callback).toHaveBeenCalledTimes(3);
});

it('should clear the interval when delay becomes null', () => {
const callback = vi.fn();
const initialProps: { delay: number | null } = { delay: 1000 };

const { rerender } = renderHook(
({ delay }: { delay: number | null }) => useInterval(callback, delay),
{
initialProps: initialProps
}
);

act(() => {
vi.advanceTimersByTime(1000);
});

expect(callback).toHaveBeenCalledTimes(1);

rerender({ delay: null });

act(() => {
vi.advanceTimersByTime(1000);
});

expect(callback).toHaveBeenCalledTimes(1);
});
});
17 changes: 17 additions & 0 deletions gbajs3/src/hooks/use-interval.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect, useLayoutEffect, useRef } from 'react';

export const useInterval = (callback: () => void, delay: number | null) => {
const savedCallback = useRef(callback);

useLayoutEffect(() => {
savedCallback.current = callback;
}, [callback]);

useEffect(() => {
if (delay === null) return;

const id = setInterval(() => savedCallback.current(), delay);

return () => clearInterval(id);
}, [delay]);
};

0 comments on commit 81127d3

Please sign in to comment.