{"id":22994377,"url":"https://github.com/donadam2/custom-react-hooks","last_synced_at":"2025-07-08T10:33:52.210Z","repository":{"id":125808115,"uuid":"402416636","full_name":"DonAdam2/custom-react-hooks","owner":"DonAdam2","description":"Includes a list of custom react hook","archived":false,"fork":false,"pushed_at":"2024-07-09T14:51:13.000Z","size":3677,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-07-09T18:56:38.715Z","etag":null,"topics":["custom-react-hooks","react","webpack"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/DonAdam2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2021-09-02T12:43:53.000Z","updated_at":"2024-07-09T14:51:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"8a450925-8a34-4e3d-8579-faf04e71adc7","html_url":"https://github.com/DonAdam2/custom-react-hooks","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"DonAdam2/webpack-react-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonAdam2%2Fcustom-react-hooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonAdam2%2Fcustom-react-hooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonAdam2%2Fcustom-react-hooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DonAdam2%2Fcustom-react-hooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DonAdam2","download_url":"https://codeload.github.com/DonAdam2/custom-react-hooks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229783795,"owners_count":18123557,"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":["custom-react-hooks","react","webpack"],"created_at":"2024-12-15T05:17:58.682Z","updated_at":"2024-12-15T05:18:00.562Z","avatar_url":"https://github.com/DonAdam2.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Table of Contents:\n- [Overview](#overview)\n- [Prerequisites](#prerequisites)\n- [Installing \u0026 getting started](#installing--getting-started)\n- [Configuring prettier](#configuring-prettier)\n- [Available hooks](#available-hooks)\n  -  [Use event listener](#use-event-listener)\n  -  [Use key press](#use-key-press)\n  -  [Use enter esc events](#use-enter-esc-events) \n  -  [Use page bottom](#use-page-bottom)\n  -  [Use window size](#use-window-size)\n  -  [Use lock scroll](#use-lock-scroll)\n  -  [Use outside click](#use-outside-click)\n  -  [Use mobile detect](#use-mobile-detect)\n  -  [Use touch screen detect](#use-touch-screen-detect)\n  -  [Use pagination](#use-pagination)\n  -  [Use async pagination](#use-async-pagination)\n  -  [Use deep linking pagination](#use-deep-linking-pagination)\n  -  [Use array](#use-array)\n  -  [Use boolean](#use-boolean)\n  -  [Use copy to clipboard](#use-copy-to-clipboard)\n  -  [Use document title](#use-document-title)\n  -  [Use external script](#use-external-script)\n  -  [Use external style](#use-external-style)\n  -  [Use countdown](#use-countdown)\n  -  [Use interval](#use-interval)\n  -  [Use timer](#use-timer)\n  -  [Use debounce](#use-debounce)\n  -  [Use fetch](#use-fetch)\n  -  [Use fetch with service](#use-fetch-with-service)\n  -  [Use magnify](#use-magnify)\n  -  [Use tilt](#use-tilt)\n  -  [Use previous value](#use-previous-value)\n  -  [Use router](#use-router)\n- [Available scripts](#available-scripts)\n\n## Overview:\n\nThis project groups a very useful list of custom react hooks and shows you how to use them as well.\n\n## Prerequisites:\n\n- nodeJS \u003e 14.X.X or Docker\n\n## Installing / Getting Started:\n\n### Development (locally):\n\n- Clone repo =\u003e `git clone git@github.com:DonAdam2/webpack-react-boilerplate.git`\n- Navigate to project directory `cd webpack-react-boilerplate`\n- Install dependencies =\u003e `yarn install`\n- Start the development server =\u003e `yarn start`\n\n### Development (using Docker):\n\n- Clone repo =\u003e `git clone git@github.com:DonAdam2/webpack-react-boilerplate.git`\n- Navigate to project directory `cd webpack-react-boilerplate`\n- Install dependencies (required for prettier) =\u003e `yarn install`\n- Start the development server =\u003e `docker-compose up web-dev`\n\n### Windows subsystem for linux \"WSL2\" (for Docker):\n\n- If you are using Windows 11 or 10, it's recommended to use WSL2:\n  - [Install WSL on windows](https://pureinfotech.com/install-wsl-windows-11/)\n  - [Install docker on windows](https://docs.docker.com/desktop/install/windows-install/)\n  - Open docker desktop app:\n    - settings =\u003e resources =\u003e WSL integration =\u003e enable required Ubuntu integration\n  - [Setup SSH keys (if you want) on windows and share it with WSL](https://devblogs.microsoft.com/commandline/sharing-ssh-keys-between-windows-and-wsl-2/)\n  - Create a new directory in ubuntu:\n  ```\n  mkdir workspace\n  cd workspace\n  ```\n  - Clone this repo into the selected Ubuntu:\n  ```\n  git clone git@github.com:DonAdam2/webpack-react-boilerplate.git\n  ```\n  - Install curl in Ubuntu:\n  ```\n  sudo apt-get install curl\n  ```\n  - Install nvm:\n  ```\n  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash\n  ```\n  - Install required node version:\n  ```\n  nvm install --lts\n  ```\n  - Install yarn globally:\n  ```\n  npm install -g yarn\n  ```\n  - Update permissions to be able to install NPM packages\n  ```\n  sudo chown -R $(whoami) ~/workspace/webpack-react-boilerplate\n  ```\n  - Install packages (for linting purposes):\n  ```\n  yarn install\n  ```\n  - Run docker for development:\n  ```\n  docker-compose up web-dev\n  ```\n\n## Docker for production (_basic setup_) (modify it to your needs):\n- Update the **_production_** section of the **_Dockerfile_** to meet your needs\n- Run the following command to build your image =\u003e `docker-compose up web-prod`\n\n## Configuring Prettier\n\nThis build relies on [Prettier formatter](https://prettier.io/) to enforce code style. And [ESLint](https://eslint.org/) for identifying problematic patterns found in the code.\n\n- Setting up prettier:\n\n  1- You can find steps on how to set up prettier formatter with WebStorm/PhpStorm [here](https://prettier.io/docs/en/webstorm.html#running-prettier-on-save-using-file-watcher).\n\n  **Notes**:\n\n  - It's better to use the local `node_modules` version of prettier instead of a global one, to avoid version conflicts (in case the globally installed version does not match the version specified in `package.json`).\n\n  2- Follow the next steps to set up **prettier** and **eslint** in **_VS Code_**:\n\n  - Install `prettier` plugin\n\n  - Install `eslint` plugin\n\n  - Open **_VS Code settings_** `CTRL + ,`:\n\n    a- Search for `formatter` =\u003e check **Format on save**\n\n    b- Search for `prettier` =\u003e add `.prettierrc` in **_Prettier: Config Path_** section \u0026\u0026 check **_Prettier: Require Config_**\n\n  3- Please refer to other tutorials if you are using a different IDE.\n\n## Available hooks\n\n  ### Use event listener:\n\n  - This hook allows you to attach the required event to the required target (default is _window_) and remove it on unmount\n  - It takes the following arguments:\n    - **eventName**: required event name to trigger\n    - **handler**: handler to attach to the given event\n    - **element**: target element (default is _window_)\n\n  ### Use key press:\n\n  - This hook makes it easy to detect when the user is pressing a specific key on their keyboard.\n  - It takes target key as an argument\n  - It returns a boolean which detects if the target key is being pressed or not\n\n  ### Use enter esc events:\n\n  - This hook allows you to fire events on enter or ESC buttons\n  - It takes the following arguments:\n    - **cancelHandler**: a function to trigger on ESC button press\n    - **confirmHandler**: a function to trigger on enter button press\n\n  ### Use page bottom:\n\n  - This hook allows you to detect if  you are at the bottom of the page.\n  - Can be used to implement infinite scroll functionality.\n\n  ### Use window size:\n\n  - This hook return the width and the height of the window\n\n  ### Use lock scroll:\n\n  - Sometimes you want to prevent your users from mbeing able to scroll the body of your page while a particular component is absolutely positioned over your page (think of a modal)\n  - It takes the following arguments:\n    - **targetElement**: target element to lock scroll (default =\u003e document.body)\n    - **immediate**: a boolean to detect when to lock scroll (default =\u003e true)\n\n  ### Use outside click:\n\n  - This hook allows you to trigger an event on the required element if clicked outside\n  - It takes the following arguments:\n    - **ref**: required element ref\n    - **callback**: a function to trigger if clicked outside the required element\n\n  ### Use mobile detect:\n\n  - This hook allows you to detect if your user is using your app from a mobile or not\n\n  ### Use touch screen detect:\n\n  - This hook allows you to detect if your user is using a touch screen device to access your app or not\n\n  ### Use pagination:\n\n  - This hook gives you pagination functionality out of the box, which can be integrated with any pagination component.\n  - It takes the following arguments:\n    - **contentPerPage**: how many elements to display per page?\n    - **count**: total length of elements\n  - It returns the following:\n    - **currentPageNum**: active page number\n    - **totalPages**: total number of pages\n    - **paginationBlocks**: pagination blocks (numbers and right, left \"can be used to add icons in the correct place\") \n    - **navigateToNextPage**: function to navigate to the next page\n    - **navigateToPrevPage**: function to navigate to the previous page\n    - **navigateToPage**: function to navigate to the required page\n    - **navigateToFirstPage**: function to navigate to the first page\n    - **navigateToLastPage**: function to navigate to the last page\n    - **navigateToNextPaginationBlock**: function to navigate to the next pagination block\n    - **navigateToPrevPaginationBlock**: function to navigate to the previous pagination block\n    - **firstContentIndex**: first element index of the current page (can be used in slice function to display the content of the current page)\n    - **lastContentIndex**: last element index of the current page (can be used in slice function to display the content of the current page)\n\n  ### Use async pagination:\n\n  - This hook gives you asynchronous pagination functionality (tied with an API call) out of the box, which can be integrated with any pagination component.\n  - It takes the following arguments (same as [Use pagination](#use-pagination) hook), plus the following:\n    - **fetchData**: function to fetch data using an API (it takes the current page as an argument)\n  - It returns the following (same as [Use pagination](#use-pagination) hook), plus the following:\n    - **resetCurrentPageNum**: function to reset current page number (usefull if you want to reset the current page number after making an API call in another part of your app \"e.g. search API\")\n  - And without the following (because we are getting data from an API):\n    - **firstContentIndex**\n    - **lastContentIndex**\n\n  ### Use deep linking pagination:\n  \n  - This hook gives you pagination functionality with deep linking (current page as search params in the URL) out of the box, which can be integrated with any pagination component.\n  - If you refresh the page you will be landed on the correct page number specified in the URL.\n  - It takes the following arguments (same as [Use pagination](#use-pagination) hook), plus the following:\n    - **deepLinkingData**: it has **pageNumKey** which gives you the ability to set search params key in the URL\n  - It returns the same as props as [Use pagination](#use-pagination) hook.\n\n  ### Use array:\n\n  - This hook makes it easier to manage an array by wrapping some functionalities of it (which can be extended to your needs).\n  - It takes an array as an argument, and it returns the new array and a list of functions to apply on it\n\n  ### Use boolean:\n  \n  - This hook gives you the ability to control boolean state\n  - It takes true or false as an argument\n  - It returns current boolean value and (toggle, on and off) functions\n\n  ### Use copy to clipboard:\n\n  -  This hook allows you to copy text to the clipboard and displays a confirmation toast (using react-toastify) on success.\n  - It returns the following:\n    - Boolean to detect if text is copied or not\n    - Function (takes the required text to copy as an argument) to copy text\n\n  ### Use document title:\n\n  - This hook allows you to change document title\n  - It takes **title** as an argument\n\n  ### Use external script:\n\n  - This hook makes it super easy to dynamically load external script and know when it's loaded. This is useful when you need to interact with a 3rd party library (Moyasar, stripe, etc) and you'd prefer to load the script when needed rather than include it in the document body.\n  - It takes the following arguments:\n    - **src**: 3rd party script URL\n    - **immediate**: a boolean to detect when to inject it in the DOM\n  - It returns a string status (idle, loading, ready, error)\n\n  ### Use external style:\n\n  - Similar to [Use external script](#use-external-script) hook but for external styles\n\n  ### Use countdown:\n\n  - This hook allows you to have a controlled count down.\n  - It takes the following arguments:\n    -  **initialCounter**: required time in seconds\n    - **callback**: a function which gets the current counter value as an argument\n  - It returns the following:\n    - **counter**: current counter value\n    - **resetCounter**: a function to reset the counter\n    - **stopCounter**: a function to stop the counter\n    - **pauseCounter**: a function to pause the counter\n    - **resumeCounter**: a function to resume the counter\n    - **isStopBtnDisabled**: a boolean to detect if the stop counter button is disabled\n    - **isPauseBtnDisabled**: a boolean to detect if the pause counter button is disabled\n    - **isResumeBtnDisabled**: a boolean to detect if the resume counter button is disabled\n\n  ### Use interval:\n  \n  - This hook allows you to have interval functionality\n\n  ### Use timer:\n\n  - This hook gives you timer functionality\n  - It returns the following:\n    - **renderedStreamDuration**: current duration to display\n    - **isStartBtnDisabled**: boolean to detect if the start button is disabled\n    - **isStopBtnDisabled**: boolean to detect if the stop button is disabled\n    - **isPauseBtnDisabled**: boolean to detect if the pause button is disabled\n    - **isResumeBtnDisabled**: boolean to detect if the resume button is disabled\n    - **startHandler**: function to start the timer\n    - **stopHandler**: function to stop the timer\n    - **pauseHandler**: function to pause the timer\n    - **resumeHandler**: function to resume the timer\n\n  ### Use debounce:\n\n  - This hook allows you to have a debounced input. For example if you want to make an API call on key press\n  - It takes the following arguments:\n    - **searchTerm**: target input value\n    - **delay**: required delay in milliseconds\n  - It returns the debounced search term which can be used to make an API\n\n  ### Use fetch:\n\n  - This hook allows you to fetch data easily on demand (using axios).\n  - It takes the following arguments:\n    - **url**: API url\n    - **options**: API options (default =\u003e null)\n    - **initialDataType**: expected data type of the response\n    - **immediate**: a boolean to detect when to make an API (default =\u003e true) (can be used to make an API on button click)\n  - It returns the following:\n    - **data**: API response on success\n    - **error**: API error on error\n    - **isLoading**: a boolean to detect API progress\n\n  ### Use fetch with service:\n\n  - This hook allows you to fetch data easily using a service (using axios with interceptors).\n  - It takes the following arguments:\n    - **api**: required service API\n    - **initialDataType**: expected data type of the response\n    - **immediate**: a boolean to detect when to make an API (default =\u003e true) (can be used to make an API on button click)\n  - It returns the same data as [Use fetch](#use-fetch) hook\n\n  ### Use magnify:\n\n  - This hook allows you to magnify the given image\n  - It takes **magnifyTimes** as an argument (decimal) which specifies how much you want to magnify your image\n  - It returns the modified image ref\n\n  ### Use tilt:\n\n  - This hook allows you to tilt the given HTML element\n  - It returns the modified HTML element ref\n\n  ### Use previous value:\n\n  - This hook returns the previous value of props or state.\n  - It takes required value of props or state as an argument\n\n  ### Use router:\n\n  - This hook wraps all react router v6 hooks and exposes just the data and methods we need\n  - It returns the following:\n    - **navigate**: navigate function from **useNavigate** hook\n    - **location**: location object from **useLocation** hook\n    - **pathname**: current pathname from **useLocation** hook\n    - **params**: an object of current params from **useParams** hook\n    - **searchParams**: an object of all search params from **useSearchParams** hook \n    - **setSearchParams**: a function to set search params from **useSearchParams** hook\n\n## Available Scripts\n\nIn the project directory, you can run:\n\n### `yarn start`\n\nRuns the app in the development mode.\u003cbr\u003e\nIt will open [http://localhost:3000](http://localhost:3000) automatically in the browser to see your app.\n\nAll changes will be injected automatically without reloading the page.\u003cbr\u003e\n\nYou will see in the console the following:\n\n- Any of the following errors:\n  1. Linting errors.\n  2. Code format errors (because of [prettier](https://prettier.io/))\n\n### `yarn build`\n\nBuilds the app for production to the `dist` folder.\u003cbr\u003e\nIt correctly bundles React in production mode and optimizes the build for the best performance.\n\nThe build is minified and the filenames include the hashes.\u003cbr\u003e\nYour app is ready to be deployed!\n\n### `yarn build:serve`\n\nServes the app on `http://localhost:8080/` from the `dist` folder to check the production version.\n\n**_Note:_** Use this script only if you ran the build script `yarn build`.\n\n### `yarn analyze-bundle`\n\nIt allows you to analyze the bundle size.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonadam2%2Fcustom-react-hooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdonadam2%2Fcustom-react-hooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdonadam2%2Fcustom-react-hooks/lists"}