-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Is a custom hook to create and manage intervals
- Loading branch information
Showing
6 changed files
with
207 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@raddix/use-interval': major | ||
--- | ||
|
||
Added the useInterval hook |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# useInterval | ||
|
||
The `useInterval` hook has an excellent API for creating and managing intervals in a simple and efficient way. | ||
|
||
Please refer to the [documentation](https://www.raddix.website/docs/interactions/use-interval) for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
{ | ||
"name": "@raddix/use-interval", | ||
"description": "A React hook for setting an interval.", | ||
"version": "0.1.0", | ||
"license": "MIT", | ||
"main": "src/index.ts", | ||
"author": "Moises Machuca Valverde <rolan.machuca@gmail.com> (https://www.moisesmachuca.com)", | ||
"homepage": "https://www.raddix.website", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/gdvu/raddix.git" | ||
}, | ||
"keywords": [ | ||
"react-hooks", | ||
"react-use-interval", | ||
"react-interval-hook", | ||
"interval", | ||
"interval-hook", | ||
"use-interval", | ||
"use-interval-hook", | ||
"use-interval-hook-react", | ||
"use-interval-react", | ||
"setInterval" | ||
], | ||
"sideEffects": false, | ||
"scripts": { | ||
"lint": "eslint \"{src,tests}/*.{ts,tsx,css}\"", | ||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist", | ||
"build": "tsup src --dts", | ||
"prepack": "clean-package", | ||
"postpack": "clean-package restore" | ||
}, | ||
"files": [ | ||
"dist", | ||
"README.md" | ||
], | ||
"peerDependencies": { | ||
"react": ">=16.8.0", | ||
"react-dom": ">=16.8.0" | ||
}, | ||
"clean-package": "../../../clean-package.config.json", | ||
"tsup": { | ||
"clean": true, | ||
"target": "es2019", | ||
"format": [ | ||
"cjs", | ||
"esm" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { useCallback, useEffect, useRef } from 'react'; | ||
|
||
export interface IntervalResult { | ||
/** Clear interval and stop the execution */ | ||
clear: () => void; | ||
/** Execute the interval */ | ||
run: () => void; | ||
} | ||
|
||
type UseInterval = ( | ||
callback: () => void, | ||
delay: number, | ||
inmediate?: boolean | ||
) => IntervalResult; | ||
|
||
export const useInterval: UseInterval = (callback, delay, inmediate = true) => { | ||
const savedCallback = useRef(callback); | ||
const id = useRef<NodeJS.Timeout | null>(null); | ||
|
||
const clearId = () => { | ||
if (!id.current) return; | ||
clearInterval(id.current); | ||
id.current = null; | ||
}; | ||
|
||
const run = useCallback(() => { | ||
if (id.current) return; | ||
const tick = () => savedCallback.current(); | ||
|
||
id.current = setInterval(tick, delay); | ||
}, [delay]); | ||
|
||
useEffect(() => { | ||
savedCallback.current = callback; | ||
}, [callback]); | ||
|
||
useEffect(() => { | ||
if (inmediate) run(); | ||
return () => clearId(); | ||
}, [run, inmediate]); | ||
|
||
return { clear: clearId, run }; | ||
}; |
91 changes: 91 additions & 0 deletions
91
packages/interactions/use-interval/tests/use-interval.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { renderHook } from '@testing-library/react'; | ||
import { useInterval } from '../src'; | ||
|
||
describe('useInterval test:', () => { | ||
beforeEach(() => { | ||
jest.useFakeTimers(); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.useRealTimers(); | ||
}); | ||
|
||
it('the interval should work', () => { | ||
const callback = jest.fn(); | ||
renderHook(() => useInterval(callback, 1000)); | ||
|
||
expect(callback).not.toBeCalled(); | ||
jest.advanceTimersByTime(2000); | ||
expect(callback).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
it('should clear the interval when the component unmounts', () => { | ||
const callback = jest.fn(); | ||
const { unmount } = renderHook(() => useInterval(callback, 1000)); | ||
|
||
expect(callback).not.toBeCalled(); | ||
unmount(); | ||
jest.advanceTimersByTime(2000); | ||
expect(callback).not.toBeCalled(); | ||
}); | ||
|
||
it('should clear the interval when the delay changes', () => { | ||
const callback = jest.fn(); | ||
const { rerender } = renderHook( | ||
({ delay }) => useInterval(callback, delay), | ||
{ | ||
initialProps: { delay: 1000 } | ||
} | ||
); | ||
|
||
expect(callback).not.toBeCalled(); | ||
rerender({ delay: 2000 }); | ||
jest.advanceTimersByTime(1000); | ||
expect(callback).not.toBeCalled(); | ||
jest.advanceTimersByTime(1000); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should clear the interval when the immediate changes', () => { | ||
const callback = jest.fn(); | ||
const { rerender } = renderHook( | ||
({ immediate }) => useInterval(callback, 1000, immediate), | ||
{ | ||
initialProps: { immediate: true } | ||
} | ||
); | ||
|
||
expect(callback).not.toBeCalled(); | ||
jest.advanceTimersByTime(1000); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
rerender({ immediate: false }); | ||
jest.advanceTimersByTime(3000); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should stop the interval when the clear function is called', () => { | ||
const callback = jest.fn(); | ||
const { result } = renderHook(() => useInterval(callback, 1000)); | ||
|
||
expect(callback).not.toBeCalled(); | ||
jest.advanceTimersByTime(1000); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
result.current.clear(); | ||
jest.advanceTimersByTime(2000); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should run the interval when the run function is called', () => { | ||
const callback = jest.fn(); | ||
const { result } = renderHook(() => useInterval(callback, 1000, false)); | ||
|
||
jest.advanceTimersByTime(2000); | ||
expect(callback).not.toBeCalled(); | ||
result.current.run(); | ||
jest.advanceTimersByTime(1000); | ||
expect(callback).toHaveBeenCalledTimes(1); | ||
result.current.run(); | ||
jest.advanceTimersByTime(1000); | ||
expect(callback).toHaveBeenCalledTimes(2); | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.