{"id":16827065,"url":"https://github.com/wojtekmaj/react-hooks","last_synced_at":"2025-04-13T06:36:48.562Z","repository":{"id":45297187,"uuid":"281911613","full_name":"wojtekmaj/react-hooks","owner":"wojtekmaj","description":"A collection of React Hooks.","archived":false,"fork":false,"pushed_at":"2024-04-30T10:09:54.000Z","size":3805,"stargazers_count":61,"open_issues_count":1,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-05-02T05:33:25.054Z","etag":null,"topics":["hooks","react","react-hooks"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wojtekmaj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"wojtekmaj"}},"created_at":"2020-07-23T09:41:52.000Z","updated_at":"2024-05-06T08:43:59.500Z","dependencies_parsed_at":"2023-10-04T04:05:26.747Z","dependency_job_id":"a7497407-6a65-4bf6-a098-1e2b93b8fb90","html_url":"https://github.com/wojtekmaj/react-hooks","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojtekmaj%2Freact-hooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojtekmaj%2Freact-hooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojtekmaj%2Freact-hooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wojtekmaj%2Freact-hooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wojtekmaj","download_url":"https://codeload.github.com/wojtekmaj/react-hooks/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248675305,"owners_count":21143763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hooks","react","react-hooks"],"created_at":"2024-10-13T11:19:32.023Z","updated_at":"2025-04-13T06:36:48.537Z","avatar_url":"https://github.com/wojtekmaj.png","language":"TypeScript","funding_links":["https://github.com/sponsors/wojtekmaj"],"categories":[],"sub_categories":[],"readme":"[![npm](https://img.shields.io/npm/v/@wojtekmaj/react-hooks.svg)](https://www.npmjs.com/package/@wojtekmaj/react-hooks) ![downloads](https://img.shields.io/npm/dt/@wojtekmaj/react-hooks.svg) [![CI](https://github.com/wojtekmaj/react-hooks/actions/workflows/ci.yml/badge.svg)](https://github.com/wojtekmaj/react-hooks/actions)\n\n# React-Hooks\n\nA collection of React Hooks.\n\n## tl;dr\n\n- Install by executing `npm install @wojtekmaj/react-hooks` or `yarn add @wojtekmaj/react-hooks`.\n- Import by adding `import { useTick } from '@wojtekmaj/react-hooks'`.\n- Do stuff with it!\n  ```ts\n  const tick = useTick();\n  ```\n\n## Server-side rendering\n\nAll hooks from this package support SSR. Some hooks use browser-only APIs, e.g. `useCurrentPosition`. Such hooks, if they are supposed to return a value, will return `null` instead.\n\n## User guide\n\n### Table of contents\n\n- [`useCurrentPosition`](#useCurrentPosition)\n- [`useDebouncedEffect`](#useDebouncedEffect)\n- [`useDebouncedState`](#useDebouncedState)\n- [`useDebouncedValue`](#useDebouncedValue)\n- [`useEventListener`](#useEventListener)\n- [`useIntersectionObserver`](#useIntersectionObserver)\n- [`useLocalStorage`](#useLocalStorage)\n- [`useMatchMedia`](#useMatchMedia)\n- [`useMutationObserver`](#useMutationObserver)\n- [`useOnLine`](#useOnLine)\n- [`usePermissionState`](#usePermissionState)\n- [`usePrefersColorSchemeDark`](#usePrefersColorSchemeDark)\n- [`usePrefersColorSchemeLight`](#usePrefersColorSchemeLight)\n- [`usePrefersReducedMotion`](#usePrefersReducedMotion)\n- [`usePrefersReducedTransparency`](#usePrefersReducedTransparency)\n- [`useResizeObserver`](#useResizeObserver)\n- [`useScrollLeft`](#useScrollLeft)\n- [`useScrollLeftDirection`](#useScrollLeftDirection)\n- [`useScrollLeftPercent`](#useScrollLeftPercent)\n- [`useScrollTop`](#useScrollTop)\n- [`useScrollTopDirection`](#useScrollTopDirection)\n- [`useScrollTopPercent`](#useScrollTopPercent)\n- [`useSessionStorage`](#useSessionStorage)\n- [`useSetInterval`](#useSetInterval)\n- [`useSetTimeout`](#useSetTimeout)\n- [`useTick`](#useTick)\n- [`useToggle`](#useToggle)\n- [`useWindowHeight`](#useWindowHeight)\n- [`useWindowWidth`](#useWindowWidth)\n\n### `useCurrentPosition`\n\nReturns current position from Geolocation API.\n\n#### Sample usage\n\n```ts\nimport { useCurrentPosition } from '@wojtekmaj/react-hooks';\n\nuseCurrentPosition(); // { latitude: 0, longitude: 0 }\n```\n\n### `useDebouncedEffect`\n\nRuns a given effect after a given delay.\n\n#### Sample usage\n\n```ts\nimport { useDebouncedEffect } from '@wojtekmaj/react-hooks';\n\nuseDebouncedEffect(\n  () =\u003e {\n    // This will run after 1 second of value not changing.\n  },\n  [value],\n  1000,\n);\n```\n\n### `useDebouncedState`\n\nReturns a debounced state and a function to update it.\n\n#### Sample usage\n\n```ts\nimport { useDebouncedState } from '@wojtekmaj/react-hooks';\n\nconst [value, setValue] = useDebouncedState('initialState', 1000); // ['initialState', Function]\n```\n\n### `useDebouncedValue`\n\nReturns a debounced value.\n\n#### Sample usage\n\n```ts\nimport { useDebouncedValue } from '@wojtekmaj/react-hooks';\n\nconst debouncedValue = useDebouncedValue(value, 1000); // This value will be updated after 1 second of value not changing.\n```\n\n### `useEventListener`\n\nAdds event listener to a given element.\n\n#### Sample usage\n\n```ts\nimport { useEventListener } from '@wojtekmaj/react-hooks';\n\nuseEventListener(element, 'click', onClick);\n```\n\n### `useIntersectionObserver`\n\nObserves a given element using [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver).\n\n#### Sample usage\n\n```ts\nimport { useIntersectionObserver } from '@wojtekmaj/react-hooks';\n\nuseIntersectionObserver(element, config, onIntersectionChange);\n```\n\n### `useLocalStorage`\n\nReturns a stateful value synchronized with [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), and a function to update it.\n\n#### Sample usage\n\n```ts\nimport { useLocalStorage } from '@wojtekmaj/react-hooks';\n\nconst [value, setValue] = useLocalStorage('myKey', 'initialState'); // ['initialState', Function]\n```\n\n### `useMatchMedia`\n\nReturns a flag which determines if the document matches the given [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries) string.\n\n#### Sample usage\n\n```ts\nimport { useMatchMedia } from '@wojtekmaj/react-hooks';\n\nconst isDesktop = useMatchMedia('screen and (min-width: 1024px)'); // true / false\n```\n\n### `useMutationObserver`\n\nObserves a given element using [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).\n\n#### Sample usage\n\n```ts\nimport { useMutationObserver } from '@wojtekmaj/react-hooks';\n\nuseMutationObserver(element, config, onMutation);\n```\n\n### `useOnLine`\n\nReturns the online status of the browser.\n\n#### Sample usage\n\n```ts\nimport { useOnLine } from '@wojtekmaj/react-hooks';\n\nconst onLine = useOnLine(); // true\n```\n\n### `usePermissionState`\n\nReturns permission state given permission name.\n\n#### Sample usage\n\n```ts\nimport { usePermissionState } from '@wojtekmaj/react-hooks';\n\nconst state = usePermissionState({ name: 'geolocation' }); // 'granted'\n```\n\n### `usePrefersColorSchemeDark`\n\nReturns a flag which determines if the document matches `(prefers-color-scheme: dark)` [media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#media_features).\n\n#### Sample usage\n\n```ts\nimport { usePrefersColorSchemeDark } from '@wojtekmaj/react-hooks';\n\nconst prefersColorSchemeDark = usePrefersColorSchemeDark(); // true\n```\n\n### `usePrefersColorSchemeLight`\n\nReturns a flag which determines if the document matches `(prefers-color-scheme: light)` [media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#media_features).\n\n#### Sample usage\n\n```ts\nimport { usePrefersColorSchemeLight } from '@wojtekmaj/react-hooks';\n\nconst prefersColorSchemeLight = usePrefersColorSchemeLight(); // true\n```\n\n### `usePrefersReducedMotion`\n\nReturns a flag which determines if the document matches `(prefers-reduced-motion: reduce)` [media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#media_features).\n\n#### Sample usage\n\n```ts\nimport { usePrefersReducedMotion } from '@wojtekmaj/react-hooks';\n\nconst prefersReducedMotion = usePrefersReducedMotion(); // true\n```\n\n### `usePrefersReducedTransparency`\n\nReturns a flag which determines if the document matches `(prefers-reduced-transparency: reduce)` [media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#media_features).\n\n#### Sample usage\n\n```ts\nimport { usePrefersReducedTransparency } from '@wojtekmaj/react-hooks';\n\nconst prefersReducedTransparency = usePrefersReducedTransparency(); // true\n```\n\n### `useResizeObserver`\n\nObserves a given element using [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).\n\n#### Sample usage\n\n```ts\nimport { useResizeObserver } from '@wojtekmaj/react-hooks';\n\nuseResizeObserver(element, config, onResize);\n```\n\n### `useScrollLeft`\n\nReturns current scroll left position in pixels.\n\n#### Sample usage\n\n```ts\nimport { useScrollLeft } from '@wojtekmaj/react-hooks';\n\nconst scrollLeft = useScrollLeft(); // 0\n```\n\n### `useScrollLeftDirection`\n\nReturns current scroll left direction.\n\n#### Sample usage\n\n```ts\nimport { useScrollLeftDirection } from '@wojtekmaj/react-hooks';\n\nconst scrollLeftDirection = useScrollLeftDirection(); // 'still' / 'left' / 'right'\n```\n\n### `useScrollLeftPercent`\n\nReturns current scroll left position in percentage.\n\n#### Sample usage\n\n```ts\nimport { useScrollLeftPercent } from '@wojtekmaj/react-hooks';\n\nconst scrollLeftPercent = useScrollLeftPercent(); // 0.5\n```\n\n### `useScrollTop`\n\nReturns current scroll top position in pixels.\n\n#### Sample usage\n\n```ts\nimport { useScrollTop } from '@wojtekmaj/react-hooks';\n\nconst scrollTop = useScrollTop(); // 0\n```\n\n### `useScrollTopDirection`\n\nReturns current scroll top direction.\n\n#### Sample usage\n\n```ts\nimport { useScrollTopDirection } from '@wojtekmaj/react-hooks';\n\nconst scrollTopDirection = useScrollTopDirection(); // 'still' / 'up' / 'down'\n```\n\n### `useScrollTopPercent`\n\nReturns current scroll top position in percentage.\n\n#### Sample usage\n\n```ts\nimport { useScrollTopPercent } from '@wojtekmaj/react-hooks';\n\nconst scrollTopPercent = useScrollTopPercent(); // 0.5\n```\n\n### `useSessionStorage`\n\nReturns a stateful value synchronized with [sessionStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage), and a function to update it.\n\n#### Sample usage\n\n```ts\nimport { useSessionStorage } from '@wojtekmaj/react-hooks';\n\nconst [value, setValue] = useSessionStorage('myKey', 'initialState'); // ['initialState', Function]\n```\n\n### `useSetInterval`\n\nRuns a given function every n milliseconds.\n\n#### Sample usage\n\n```ts\nimport { useSetInterval } from '@wojtekmaj/react-hooks';\n\nuseSetInterval(fn, 1000);\n```\n\n### `useSetTimeout`\n\nRuns a given function after n milliseconds.\n\n#### Sample usage\n\n```ts\nimport { useSetTimeout } from '@wojtekmaj/react-hooks';\n\nuseSetTimeout(fn, 1000);\n```\n\n### `useTick`\n\nCounts from 0, increasing the number returned every n milliseconds.\n\n#### Sample usage\n\n```ts\nimport { useTick } from '@wojtekmaj/react-hooks';\n\nconst tick = useTick(1000); // 0 … 🕐 … 1 … 🕑 … 2 …\n```\n\n### `useToggle`\n\nReturns a flag and a function to toggle it.\n\n#### Sample usage\n\n```ts\nimport { useToggle } from '@wojtekmaj/react-hooks';\n\nconst [value, toggleValue] = useToggle(); // [false, Function]\n```\n\n### `useWindowHeight`\n\nReturns the interior height of the window in pixels.\n\n#### Sample usage\n\n```ts\nimport { useWindowHeight } from '@wojtekmaj/react-hooks';\n\nconst windowWidth = useWindowHeight(); // 900\n```\n\n### `useWindowWidth`\n\nReturns the interior width of the window in pixels.\n\n#### Sample usage\n\n```ts\nimport { useWindowWidth } from '@wojtekmaj/react-hooks';\n\nconst windowWidth = useWindowWidth(); // 1440\n```\n\n## License\n\nThe MIT License.\n\n## Author\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd \u003e\n      \u003cimg src=\"https://avatars.githubusercontent.com/u/5426427?v=4\u0026s=128\" width=\"64\" height=\"64\" alt=\"Wojciech Maj\"\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003ca href=\"https://github.com/wojtekmaj\"\u003eWojciech Maj\u003c/a\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwojtekmaj%2Freact-hooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwojtekmaj%2Freact-hooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwojtekmaj%2Freact-hooks/lists"}