{"_id":"react-util-hooks","_rev":"60-0f9ccda004d0a69b397f6f6fc4e66fbe","time":{"0.6.0":"2021-09-04T17:08:52.066Z","0.6.1":"2021-09-04T17:08:52.066Z","0.6.2":"2021-09-04T17:08:52.066Z","0.6.3":"2021-09-04T17:08:52.066Z","0.6.4":"2021-09-04T17:08:52.066Z","created":"2021-09-09T08:35:29.141Z","0.1.0":"2021-09-09T08:35:29.299Z","modified":"2022-05-15T07:16:05.933Z","0.2.0":"2022-01-14T17:43:26.212Z","0.2.1":"2022-01-14T18:03:36.722Z","0.2.2":"2022-01-14T18:07:28.440Z"},"name":"react-util-hooks","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"react-util-hooks","version":"0.1.0","description":"This Library Contains Some Useful Hooks For ReactJS","main":"dist/index.cjs.js","module":"dist/index.esm.js","type":"module","types":"dist/types","scripts":{"build":"rollup -c rollup.config.ts","format":"prettier --write \"src/**/*.ts\" \"dist/**/*.ts\" \"dist/**/*.js\"","lint":"tslint -p tsconfig.json","test":"echo \"No test specified\"","commit":"git add . && cz","semantic-release":"semantic-release --branches main"},"repository":{"type":"git","url":"git+https://github.com/prantaDutta/react-util-hooks.git"},"bugs":{"url":"https://github.com/prantaDutta/react-util-hooks.git/issues"},"homepage":"https://github.com/prantaDutta/react-util-hooks#readme","author":{"name":"PRANTA Dutta"},"license":"ISC","keywords":["react","reactJS","typescript","react-hooks","react-util-hooks"],"devDependencies":{"@rollup/plugin-node-resolve":"7.1.1","@types/react":"^17.0.5","cz-conventional-changelog":"^3.3.0","prettier":"^2.3.0","rollup":"1.31.0","rollup-plugin-typescript2":"0.25.3","semantic-release":"^17.4.7","tslint":"^6.1.3","tslint-config-prettier":"^1.18.0","typescript":"^4.2.4"},"peerDependencies":{"react":"^17.0.2"},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"gitHead":"0c1f8d8a35cd7b446a79fee69759902dd57a3bc3","_id":"react-util-hooks@0.1.0","_nodeVersion":"14.17.5","_npmVersion":"6.14.14","dist":{"integrity":"sha512-nrcW2ko+7WwMPiLI/en9qdjsnq5oNrRFkUqZCSCpqswHiBVe5BoAYwc7P0L50W0AhNK8GsC+ZYTF/zkRZByUjQ==","shasum":"3769c87382ae35e927cd29fcbc3b4735ecc20f5d","tarball":"https://registry.npmjs.org/react-util-hooks/-/react-util-hooks-0.1.0.tgz","fileCount":35,"unpackedSize":99253,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhOcdRCRA9TVsSAnZWagAAG6YP+wXOS4MI46Z0Tc4xACyo\nDjyCmYWXI2FCSfM6nvjS8KP0cEJMws1seATC4Nfid5712m0ZuBtHHhvoV7aT\n1EbOuSz83dZ0Bkt2cRzGTk1yVhTUjBQGZP2R819KKzO4ykCvodHn3raac5AD\ncOqNU5ovTMmJRBPs7sFa3RHYJJYWhgvRURQomoGERFHpJDuN2AHMMrpN/0yP\nOdtcJIKkBziHovDDvl1qzZzcUSZat2VrvDVlJBi+EJ9RM0Iw/wOH9Apjk3sm\neroyaGcISrKi6uDJqX5Si1HPhpPXBdHXd73kp6zR2wqBylpcgSrSakjPlYqv\nMhIGBLWXErEVMPHQUjwntBGk1LStyUA9o21Mp6POu55gMzRMAWwISE596a4g\n3gLbfRjEkyQHkymCrp9hFhU60kaOK07E1ThmpX+MFw8+nvvedZgpXcBOkDDQ\nbr0Xy0g6EbcRWv9rYflnh0H1q2/Gn3aWiSH+P+Eob5Zsu+QEvQWWm8WuBt3B\nODvgPzt1r/mZmbs+qLlTfSD3bJyvatTAn08qOBraV14MIt0vXADGZtw27aRX\nOnSN7POllMR5wTPEK7n6ljWX0Z8B48BlrW6qnDzz67QofmsfGndKkSAaelpQ\n3y6q/TlfzsRPxS3UA1+aZcqzCr6umMWdQngVSwwAFZdhc1F7IFjAywEwB1kR\nq81/\r\n=u9Yt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDo0X5+KoEarDMfzpcWM3QEZVnmNjUOGM4wlHmGeEDKCwIgRkqYQ36ReWXlTzTQQqrLI6PNbX2Q3E3QnvoLpvBzcdg="}]},"_npmUser":{"name":"prantadutta","email":"prantadutta1997@gmail.com"},"directories":{},"maintainers":[{"name":"prantadutta","email":"prantadutta1997@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-util-hooks_0.1.0_1631176529142_0.7951914051289686"},"_hasShrinkwrap":false},"0.2.0":{"version":"0.2.0","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=12"},"scripts":{"start":"tsdx watch","build":"tsdx build","test":"tsdx test --passWithNoTests","lint":"tsdx lint","prepare":"tsdx build","size":"size-limit","analyze":"size-limit --why"},"peerDependencies":{"react":">=16"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"prettier":{"printWidth":80,"semi":false,"singleQuote":true,"trailingComma":"es5"},"name":"react-util-hooks","author":{"name":"PRANTA Dutta"},"module":"dist/react-util-hooks.esm.js","size-limit":[{"path":"dist/react-util-hooks.cjs.production.min.js","limit":"10 KB"},{"path":"dist/react-util-hooks.esm.js","limit":"10 KB"}],"devDependencies":{"@rollup/plugin-replace":"^3.0.1","@size-limit/preset-small-lib":"^7.0.5","@types/react":"^17.0.38","@types/react-dom":"^17.0.11","husky":"^7.0.4","react":"^17.0.2","react-dom":"^17.0.2","size-limit":"^7.0.5","tsdx":"^0.14.1","tslib":"^2.3.1","typescript":"^4.5.4"},"description":"When using react(or other frameworks like NextJS and Gatsby), we often need to use some kind of hooks to make our lives a bit easier. But each time, we have to create these hooks ourselves. So I created this library where you can find all the utility hook","licenseText":"MIT License\n\nCopyright (c) 2022 PRANTA Dutta\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","_id":"react-util-hooks@0.2.0","dist":{"shasum":"96a43fa8f3960aed73e3e98dc5378caa1345116c","integrity":"sha512-UU8WXSQF0I1dqTUhxIgowWR/ECj39NDYl/Eqm/BcB9IFgON+xr6MsMJHazn/EGBwOhv9TkerLzTdlUFClrGYRA==","tarball":"https://registry.npmjs.org/react-util-hooks/-/react-util-hooks-0.2.0.tgz","fileCount":83,"unpackedSize":491161,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4bY+CRA9TVsSAnZWagAAtSEP/jicuTFv9uGwqj6Qk9fF\nws4DtMcqERM4tzRICYKJZWtNZTia3LU6ITFDxEfXuWN2TOyszelQJylVlC6Y\n1qyXLmqdihd6fIFubjgf2QJ+Y3Qg/wjIqKcGqb+agyEHopoRZywTES2rTqot\n53cpf+ZknudrvW6SQmOlhIgMpvhE7Bkc0kuzA2zpaW6Z090n+GPA4qNHmrjs\ntrq+jqu42GmS6guaz8slJJEIg7MJH6plVfRv0XBEl1L/g6CH/9NS++5jEXnc\nvC5d6qrZRwmekNQp5ABfSMV5YiURk8/BKQxX/iNVBXKAIxHJLVkRzcqaNOVs\nqK5hsHKRkhi90n3wX3Bo/6R/aisVcMyoIpube/XhRyJ7JPTfgJ4W+1xbnHP0\nBKulzMQTj6ZteEjx3/lFgTV3HAo2f+8azOxSBScOxfoOIRzVVcYu1KN5ZNh+\nSDUpHGRjMid4p/g7NahN+vktH+oyN+aFd2YrirXcdIFlIQMc3Ijha3WhQCUy\nNnBYOBVxM970996l+EdDDjM2hAgkcjJjPpL5eDhQuqGC8jlksWvux/queaWB\nnTNWCcM/mIi/IaY109HwpILbByGTcx/e5vegIyV4cDDzI91P5Kd/oS0g0Hn3\nL0rBWPDqhiKarSklQpzTKAa6eZL9q+G8nvfIOWAtk9hAOt36TVjTb1YzAqgV\nZRew\r\n=cOKb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHNmavHNmzKu7bCNB+/o/RQ1uHOtap2/5bvbi9BmVzBvAiAtRSiUsazZPFzy4GRfhSkMf3Bsc/R8g/Y3wd2WQAHYDQ=="}]},"_npmUser":{"name":"prantadutta","email":"prantadutta1997@gmail.com"},"directories":{},"maintainers":[{"name":"prantadutta","email":"prantadutta1997@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-util-hooks_0.2.0_1642182206070_0.995333436369648"},"_hasShrinkwrap":false},"0.2.1":{"version":"0.2.1","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=12"},"scripts":{"start":"tsdx watch","build":"tsdx build","test":"tsdx test --passWithNoTests","lint":"tsdx lint","prepare":"tsdx build","size":"size-limit","analyze":"size-limit --why"},"peerDependencies":{"react":">=16"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"prettier":{"printWidth":80,"semi":false,"singleQuote":true,"trailingComma":"es5"},"name":"react-util-hooks","author":{"name":"PRANTA Dutta"},"module":"dist/react-util-hooks.esm.js","size-limit":[{"path":"dist/react-util-hooks.cjs.production.min.js","limit":"10 KB"},{"path":"dist/react-util-hooks.esm.js","limit":"10 KB"}],"devDependencies":{"@rollup/plugin-replace":"^3.0.1","@size-limit/preset-small-lib":"^7.0.5","@types/react":"^17.0.38","@types/react-dom":"^17.0.11","husky":"^7.0.4","react":"^17.0.2","react-dom":"^17.0.2","size-limit":"^7.0.5","tsdx":"^0.14.1","tslib":"^2.3.1","typescript":"^4.5.4"},"description":"When using react(or other frameworks like NextJS and Gatsby), we often need to use some kind of hooks to make our lives a bit easier. But each time, we have to create these hooks ourselves. So I created this library where you can find all the utility hook","licenseText":"MIT License\n\nCopyright (c) 2022 PRANTA Dutta\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","_id":"react-util-hooks@0.2.1","dist":{"shasum":"304541fef07982f4dfbc8f50447d6fe4a1f7c9a3","integrity":"sha512-lhLwJfqqGRTTy6TLOQRA68XXL7fE1asMQZCObOc1MhyWSF9OGy1eArDA8I0SktV0Uxc9Fx3RToQ0RgRfWOdkRA==","tarball":"https://registry.npmjs.org/react-util-hooks/-/react-util-hooks-0.2.1.tgz","fileCount":83,"unpackedSize":497627,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4br4CRA9TVsSAnZWagAAtrEP/3IXE9N40T5QcYjMHPCM\nPgvmbevDfcL1MeWxQcHbgCBW5JhzH3tsnyXYJrGSxtiedN9epFS4nm2RKEZf\nhgfxDUzUtC6hmqeg+2wrlwlag7E4yg7Br5NIu/6iwsaWOhoe/49hkm5RxA2g\nzHyEUb3j+56go5o3X/SGNzrgbkkjJFIxUMpjkeMlyP6YFAgfgL32fp29sptF\nsnDjV/kHgQ+hojWMLuQ8lJuDGLPL4tfCEVmsXp+5c5B8sm4n63tSCFth9enJ\nBk17hu9+SsLXApbRUVqWWz8RpuS33fr2QWQCPQHWWjbTBZ97nhH2tALoer7X\nOASeXxB+9k4DWktZymxTKScaqIEwnZk5mGon9/IN6ZIDlZAwRZPBT3B518Hw\n11CVoCycAuqBSiQaH49qIkZeWwKT/uN/VPv9rrHipPsFVWCJZ8gR6TQuv/bY\npfQ2kl8apnq99W4pqAJwAFyKkoOIat98xIU5pntd6OdWn2OJ9vNobhJ4lOpn\ntqQqJaTb8wQ77RerAW1WhAN39kQICSyhKz81L93+J6XoP/Ko+d2rNM1Qo1iG\nKRE68VJumxloOkTW0vxboaLY24nVD5SaEMDELWjdC1ED0UyEqQAqcS0LajGp\nLiJUUnh9D5/kGRdz+RBt/XwkXf2zntzg/qE0+33utZslH7PeU6U9DlEaBObS\nD+Tg\r\n=zU0b\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICI82QnJpJjm2h4hk3UY0/BixYENWAjYK7vsaBoJ2a1FAiEA+yqEmWRXsDI/+JUbREHqgQqyEU8krVjIeOt/RXnvShY="}]},"_npmUser":{"name":"prantadutta","email":"prantadutta1997@gmail.com"},"directories":{},"maintainers":[{"name":"prantadutta","email":"prantadutta1997@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-util-hooks_0.2.1_1642183416529_0.8917265575241138"},"_hasShrinkwrap":false},"0.2.2":{"version":"0.2.2","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=12"},"scripts":{"start":"tsdx watch","build":"tsdx build","test":"tsdx test --passWithNoTests","lint":"tsdx lint","prepare":"tsdx build","size":"size-limit","analyze":"size-limit --why"},"peerDependencies":{"react":">=16"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"prettier":{"printWidth":80,"semi":false,"singleQuote":true,"trailingComma":"es5"},"name":"react-util-hooks","author":{"name":"PRANTA Dutta"},"module":"dist/react-util-hooks.esm.js","size-limit":[{"path":"dist/react-util-hooks.cjs.production.min.js","limit":"10 KB"},{"path":"dist/react-util-hooks.esm.js","limit":"10 KB"}],"devDependencies":{"@rollup/plugin-replace":"^3.0.1","@size-limit/preset-small-lib":"^7.0.5","@types/react":"^17.0.38","@types/react-dom":"^17.0.11","husky":"^7.0.4","react":"^17.0.2","react-dom":"^17.0.2","size-limit":"^7.0.5","tsdx":"^0.14.1","tslib":"^2.3.1","typescript":"^4.5.4"},"description":"When using react(or other frameworks like NextJS and Gatsby), we often need to use some kind of hooks to make our lives a bit easier. But each time, we have to create these hooks ourselves. So I created this library where you can find all the utility hook","licenseText":"MIT License\n\nCopyright (c) 2022 PRANTA Dutta\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","_id":"react-util-hooks@0.2.2","dist":{"shasum":"1dcc1bc62868502ae3489e6ecd254563ce14cf81","integrity":"sha512-SWFg1Whg/sAqvVy+/AROyVIPSzvWbfnIgeFwipqbShfHhrzAuVnLDM5Laz/GT7jCITG0LLnwtGKrMvXDT8zh7w==","tarball":"https://registry.npmjs.org/react-util-hooks/-/react-util-hooks-0.2.2.tgz","fileCount":83,"unpackedSize":497642,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4bvgCRA9TVsSAnZWagAATwoP/2Apazw/q1VAL8V9rNZ5\nRKLv1bUGYgAzXIHLDFvNPKaikB0HH2u59HU9kHD3qMW3TXjpRT1bMDnCo3gp\nn55HUxe30XHyxixQu0aH/dhLGFunS2AAthrkLiopJPYienR5NEJgYoonFlwD\nfTT/j3jla3p7/vZJr7dnreoVfnx7ZHv41Fc+jB5zxzQKWvbyRfJ0sTU6lxk0\nXp1JsglRLuqa0+2B+VIh3uuskWic3GjJ81e9KJosGKBTWLcGs+PsKtR2WW/o\ntYEMEZ4l/rr/pOxhK6m/0KUTUxliiqdOL1wjE+wedcu/oq4uJhWbIKtOgeae\nnuG+i4h9mQcWhMTBpqpVi9jrSiZysUbdNuhk6OSsLuV/9p5G9COsfUod9hax\ndoHTNyMEwQI5iDDDOnGhtwfGyB7I8FfN0L1XLYazAeM/FGWFpPOvaATmOjMG\nYt/RegSdwk/XJwgvOGdbbxxF6LQLdV4BSZqdmAh0KEurrkTo+GhrOvXIpV56\nwwlQudQGo6IktntDElp8eBJlwtOl41C1JxjQ9bK5ivsedn1ymYlrDzhcGaj/\nJicKMaqWxZSLp42+Fk36Tsw8U0VoCzeb4zi/T8Tk71Sz8D3IzGWBVA6y+Vzb\nSQE/Q+nI0JrQ5KJg+2QhLXES5KOUof3047xwIWmFA5NzwyDnfKUX4sPf3yE2\nPPzM\r\n=4nix\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICo2jGfbflOyDPSq6iQjflUsc1W+zWWVNbX3oJxt3Oa9AiB2NhdqCm2bdiBuoCG7Nun1jKFcOy3fRokBRgWCTLVC5A=="}]},"_npmUser":{"name":"prantadutta","email":"prantadutta1997@gmail.com"},"directories":{},"maintainers":[{"name":"prantadutta","email":"prantadutta1997@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-util-hooks_0.2.2_1642183648300_0.40408158267314986"},"_hasShrinkwrap":false}},"maintainers":[{"name":"prantadutta","email":"prantadutta1997@gmail.com"}],"description":"When using react(or other frameworks like NextJS and Gatsby), we often need to use some kind of hooks to make our lives a bit easier. But each time, we have to create these hooks ourselves. So I created this library where you can find all the utility hook","author":{"name":"PRANTA Dutta"},"license":"MIT","readme":"# 🛠 All of Your Utility Hooks in One Place.\n\nWhen using react(or other frameworks like NextJS and Gatsby), we often need to use some kind of hooks to make our lives\na bit easier. But each time, we have to create these hooks ourselves. So I created this library where you can find all\nthe utility hooks you ever need (Kinda).\n\n### These Lines are _Extremely_ Important\n\nI don't own any of these hooks. I found these hooks on the internet and every time I wanted to use them, I had to search\nagain and again. So I created this library so that I can use it anytime I want. Don't worry you can use it too 🤝🤝🤝\n\n### Original Hooks Taken from [useHook.ts](https://usehooks-typescript.com/) & [useHook.com](https://usehooks.com/)\n\n### What are React Hooks?\n\nHooks are a new addition in React that lets you use state and other React features without writing a class. This library\nprovides easy to understand code examples to help you learn how hooks work and inspire you to take advantage of them in\nyour next project. Learn more from [react docs](https://reactjs.org/docs/hooks-overview.html)\n\n_Table of contents:_\n\n- [Installation](#installation) 💻\n- [Features](#features) 📋\n- [Hooks](#hooks) 🔗\n- [Usage](#usage) 🖨️\n- [Project Status](#project-status) ✔️\n- [Support Me](#support-me) 🙏\n- [🤓 References](#references) 🌐\n\n## Installation\n\n```bash\nnpm add react-util-hooks\n// OR\nyarn add react-util-hooks\n```\n\n## Features\n\n- Doesn't have any Dependency (Except for React)\n- Only 5 KB in Minified/GZIP\n- 100% Modular. Just Use the Hooks you need.\n- Detailed Documentation with Example\n- Written in Typescript\n- Most of the hooks are Generic\n\n## Hooks\n\n- [useAsync](#useasync)\n- [useBoolean](#useboolean)\n- [useCopyToClipboard](#usecopytoclipboard)\n- [useCounter](#usecounter)\n- [useClickAnyWhere](#useclickanywhere)\n- [useDarkMode](#usedarkmode)\n- [useDebounce](#usedebounce)\n- [useElementSize](#useelementsize)\n- [useEventListener](#useeventlistener)\n- [useFetch](#usefetch)\n- [useHover](#usehover)\n- [useImageOnLoad](#useimageonload)\n- [useIntersectionObserver](#useintersectionobserver)\n- [useInterval](#useinterval)\n- [useIsClient](#useisclient)\n- [useIsFirstRender](#useisfirstrender)\n- [useKeyPress](#usekeypress)\n- [useLocalStorage](#uselocalstorage)\n- [useLockedBody](#uselockedbody)\n- [useMedia](#usemedia)\n- [useOnClickOutside](#useonclickoutside)\n- [useOnScreen](#useonscreen)\n- [usePrevious](#useprevious)\n- [useReadLocalStorage](#usereadlocalstorage)\n- [useScreen](#usescreen)\n- [useScript](#usescript)\n- [useSessionStorage](#usesessionstorage)\n- [useSessionStorageWithObject](#usesessionstoragewithobject)\n- [useSsr](#usessr)\n- [useTimeout](#usetimeout)\n- [useToggle](#usetoggle)\n- [useUpdateEffect](#useupdateeffect)\n- [useWindowSize](#usewindowsize)\n\n## Usage\n\n### Important\n\nThis library doesn't have any default export.\n\nSo you shouldn't do the following (remember you can, but you shouldn't):\n\n```js\n    import ReactUtilHooks from 'react-util-hooks'\n    // OR\n    import * as ReactUtilHooks from 'react-util-hooks'\n```\n\nInstead, you should only import the hook/hooks you need. Let's say, you only need useClient hook. Do the following\n\n```js\n    import {useIsClient} from 'react-util-hooks'\n    // OR\n    import {useIsClient, useFetch} from 'react-util-hooks'\n```\n\nThis way, your bundle size will be much smaller, and your app performance will be better. You can also do the not\nrecommended way\n\n```jsx\n    import ReactUtilHooks from 'react-util-hooks'\n    // Not Recommended\n    function app() {\n        const isClient = ReactUtilHooks.useIsClient()\n    }\n```\n\n### useAsync\n\nIt's generally a good practice to indicate to users the status of any async request. An example would be fetching data\nfrom an API and displaying a loading indicator before rendering the results. Another example would be a form where you\nwant to disable the submit button when the submission is pending and then display either a success or error message when\nit completes. Rather than litter your components with a bunch of useState calls to keep track of the state of an async\nfunction, you can use our custom hook which takes an async function as an input and returns the value, error, and status\nvalues we need to properly update our UI. Possible values for status prop are: \"idle\", \"pending\", \"success\", \"error\".\n\n```jsx\n    function App() {\n        const {execute, status, value, error} = useAsync(myFunction, false);\n        return (\n            <div>\n                {status === \"idle\" && <div>Start your journey by clicking a button</div>}\n                {status === \"success\" && <div>{value}</div>}\n                {status === \"error\" && <div>{error}</div>}\n                <button onClick={execute} disabled={status === \"pending\"}>\n                    {status !== \"pending\" ? \"Click me\" : \"Loading...\"}\n                </button>\n            </div>\n        );\n    }\n```\n\n### useBoolean\n\nA simple abstraction to play with a boolean, don't repeat yourself.\n\n```\n    export default function Component() {\n        const { value, setValue, setTrue, setFalse, toggle } = useBoolean(false)\n        \n        // Just an example to use \"setValue\"\n        const customToggle = () => setValue(x => !x)\n        \n        return (\n        <>\n          <p>\n            Value is <code>{value.toString()}</code>\n          </p>\n          <button onClick={setTrue}>set true</button>\n          <button onClick={setFalse}>set false</button>\n          <button onClick={toggle}>toggle</button>\n          <button onClick={customToggle}>custom toggle</button>\n        </>\n        )\n    }\n```\n\n### useCopyToClipboard\n\nThis React hook gives you a copy method to save a string in the clipboard and the copied value (default: null).\n\nIf anything doesn't work, it prints a warning in the console and the value will be null.\n\n```\n    export default function Component() {\n      const [value, copy] = useCopyToClipboard()\n      return (\n        <>\n          <h1>Click to copy:</h1>\n          <div style={{ display: 'flex' }}>\n            <button onClick={() => copy('A')}>A</button>\n            <button onClick={() => copy('B')}>B</button>\n            <button onClick={() => copy('C')}>C</button>\n          </div>\n          <p>Copied value: {value ?? 'Nothing is copied yet!'}</p>\n        </>\n      )\n    }\n```\n\n### useCounter\n\nA simple abstraction to play with a counter, don't repeat yourself.\n\n```\n    export default function Component() {\n      const { count, setCount, increment, decrement, reset } = useCounter(0)\n    \n      const multiplyBy2 = () => setCount(x => x * 2)\n    \n      return (\n        <>\n          <p>Count is {count}</p>\n          <button onClick={increment}>Increment</button>\n          <button onClick={decrement}>Decrement</button>\n          <button onClick={reset}>Reset</button>\n          <button onClick={multiplyBy2}>Multiply by 2</button>\n        </>\n      )\n    }\n```\n\n### useClickAnyWhere\n\nThis simple React hook offers you a click event listener at the page level, don't repeat yourself.\n\n```typescript jsx\n    import React, { useState } from 'react'\n    import { useClickAnyWhere } from 'react-util-hooks'\n    \n    export default function Component() {\n      const [count, setCount] = useState(0)\n    \n      useClickAnyWhere(() => {\n        setCount(prev => prev + 1)\n      })\n    \n      return <p>Click count: {count}</p>\n    }\n```\n\n### useDarkMode\n\nThis React Hook offers you an interface to enable, disable, toggle and read the dark theme mode. The returned value (isDarkMode) is a boolean to let you be able to use with your logic.\n\nIt uses internally useLocalStorage() to persist the value and listens the OS color scheme preferences.\n\n```\n    export default function Component() {\n      const { isDarkMode, toggle, enable, disable } = useDarkMode()\n    \n      return (\n        <div>\n          <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>\n          <button onClick={toggle}>Toggle</button>\n          <button onClick={enable}>Enable</button>\n          <button onClick={disable}>Disable</button>\n        </div>\n      )\n    }\n```\n\n### useDebounce\n\nThis React hook helps to limit that the component is re-rendered too many times. Imagine that you want to execute a\nfunction on an event that executes several hundred times per second such as moving the mouse or scrolling. This may\ncause the application to lag. To prevent this, the debounce uses an internal timer to execute the callback function\nevery xx seconds (2nd parameter). Consider the example below. Each time the user enters the field, the onChange event is\ntriggered. On the other hand, the unfolded variable is updated at most every 500ms. If you have to make an API call to\nfind the elements that match the search term, you can do so by monitoring the unpacked variable, which will be more\neconomical.\n\n```jsx\n    export default function Component() {\n        const [value, setValue] = useState < string > ('')\n        const debouncedValue = useDebounce < string > (value, 500)\n    \n        const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n            setValue(event.target.value)\n        }\n        // Fetch API (optional)\n        useEffect(() => {\n            // Do fetch here...\n            // Triggers when \"debouncedValue\" changes\n        }, [debouncedValue])\n        return (\n            <div>\n                <p>Value real-time: {value}</p>\n                <p>Debounced value: {debouncedValue}</p>\n                <input type=\"text\" value={value} onChange={handleChange}/>\n            </div>\n        )\n    }\n```\n\n### useElementSize\n\nThis hook helps you to dynamically recover the width and the height of an HTML element. Dimensions are updated when\nresizing the window.\n\n```jsx\n    export default function Component() {\n        const squareRef = useRef(null)\n        const {width, height} = useElementSize(squareRef)\n        return (\n            <>\n                <p>{`the square width is ${width}px and height ${height}px`}</p>\n                <div\n                    ref={squareRef}\n                    style={{\n                        width: '50%',\n                        paddingTop: '50%',\n                        backgroundColor: 'aquamarine',\n                        margin: 'auto',\n                    }}\n                />\n            </>\n        )\n    }\n```\n\n### useEventListener\n\nUse EventListener with simplicity by React Hook. It takes as parameters an ```eventName```, a call-back\nfunctions ```(handler)``` and optionally a reference ```element```. You can see above two examples using ```useRef```\nand ```window``` based event.\n\n```jsx\n    export default function Component() {\n        // Define button ref\n        const buttonRef = useRef < HTMLButtonElement > (null)\n        const onScroll = (event: Event) => {\n            console.log('window scrolled!', event)\n        }\n        const onClick = (event: Event) => {\n            console.log('button clicked!', event)\n        }\n        // example with window based event\n        useEventListener('scroll', onScroll)\n        // example with element based event\n        useEventListener('click', onClick, buttonRef)\n        return (\n            <div style={{minHeight: '200vh'}}>\n                <button ref={buttonRef}>Click me</button>\n            </div>\n        )\n    }\n```\n\n### useFetch\n\nHere is a React Hook which aims to retrieve data on an API using the native Fetch API.\nI used a reducer to separate state logic and simplify testing via functional style.\nThe received data is saved (cached) in the application via useRef, but you can use LocalStorage\n[(see useLocalStorage())](uselocalstorage) or a caching solution to persist the data. The fetch is executed when\nthe component is mounted and if the url changes. If ever the url is undefined, or if the component is unmounted\nbefore the data is recovered, the fetch will not be called. This hook also takes the request config\nas a second parameter in order to be able to pass the authorization token in the header of the request,\nfor example. Be careful though, the latter does not trigger a re-rendering in case of modification,\ngo through the url params to dynamically change the request.\n\n```jsx\n    export const DogImage: FC = () => {\n        const {data,} = useFetch < DogImageType > ({\n            url: \"https://dog.ceo/api/breed/beagle/images/random\",\n            init: {/* options here*/}\n        });\n    \n        return <>{data ? <img src={data.message} alt=\"dog\"></img> : <div>Loading</div>}</>\n    }\n```\n\n### useHover\n\nReact UI sensor hook that determine if the mouse element is in the hover element using Javascript Typescript instead\nCSS. This way you can separate the logic from the UI.\n\n```jsx\n    export default function Component() {\n        const hoverRef = useRef(null)\n        const isHover = useHover(hoverRef)\n    \n        return (\n            <div ref={hoverRef}>\n                {`The current div is ${isHover ? `hovered` : `unhovered`}`}\n            </div>\n        )\n    }\n```\n\n### useImageOnLoad\n\nA simple React Hook that helps you improve UX while images are loading. Rather than having an image that \"unfolds\" from\ntop to bottom, we load a smaller version first which will be blurred and which will be replaced by the normal size image\nonce loaded. You can see an implementation of this hook on this\nsite: [React Gallery](https://react-gallery-ux.netlify.app/). Don't hesitate to take the logic and write your own CSS\ninstead.\n\n```jsx\n    import React, {CSSProperties} from 'react'\n    import {useImageOnLoad} from 'react-util-hooks'\n    \n    export default function Component() {\n        const {handleImageOnLoad, css} = useImageOnLoad()\n        const style: { [key: string]: CSSProperties } = {\n            wrap: {\n                position: 'relative',\n                width: 600,\n                height: 600,\n            },\n            image: {\n                position: 'absolute',\n                width: `100%`,\n                height: `100%`,\n            },\n        }\n        return (\n            <div style={style.wrap}>\n                {/* Small image load fast */}\n                <img\n                    style={{...style.image, ...css.thumbnail}}\n                    src=\"https://via.placeholder.com/150\"\n                    alt=\"thumbnail\"\n                />\n                {/* Full size image */}\n                <img\n                    onLoad={handleImageOnLoad}\n                    style={{...style.image, ...css.fullSize}}\n                    src=\"https://via.placeholder.com/600\"\n                    alt=\"fullImage\"\n                />\n            </div>\n        )\n    }\n```\n\n### useIntersectionObserver\n\nThis React Hook detects visibility of a component on the viewport using\nthe [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) API natively\npresent in the browser. It can be very useful to lazy-loading of images, implementing \"infinite scrolling\" or starting\nanimations for example. Your must pass the ref element (from useRef()). It takes optionally root, rootMargin and\nthreshold arguments from the native IntersectionObserver API and freezeOnceVisible to only catch the first appearance\ntoo. It returns the full IntersectionObserver's entry object.\n\n```jsx\n    import React, {FC, useRef} from 'react'\n    import {useIntersectionObserver} from 'react-util-hooks'\n    \n    const Section: FC = ({children}) => {\n        const ref = useRef < HTMLDivElement | null > (null)\n        const entry = useIntersectionObserver(ref, {})\n        const isVisible = !!entry?.isIntersecting\n        console.log(`Render Section ${children?.toString()}`, {isVisible})\n        return (\n            <div\n                ref={ref}\n                style={{\n                    minHeight: '100vh',\n                    display: 'flex',\n                    border: '1px dashed #000',\n                }}\n            >\n                <div style={{margin: 'auto'}}>{children}</div>\n            </div>\n        )\n    }\n    export default function Component() {\n        return (\n            <>\n                <Section key=\"1\">div n°1</Section>\n                <Section key=\"2\">div n°2</Section>\n                <Section key=\"3\">div n°3</Section>\n                <Section key=\"4\">div n°4</Section>\n                <Section key=\"5\">div n°5</Section>\n            </>\n        )\n    }\n```\n\n### useInterval\n\nUse [setInterval](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval) in functional\nReact component with the same API. Set your callback function as a first parameter and a delay (in milliseconds) for the\nsecond argument. You can also stop the timer passing null instead the delay. The main difference between the setInterval\nyou know and this useInterval hook is that its arguments are \"dynamic\". You can get more information in\nthe [Dan Abramov's blog post](https://overreacted.io/making-setinterval-declarative-with-react-hooks/).\n\n```jsx\n    import React, {useState, ChangeEvent} from 'react'\n    import useInterval from './useInterval'\n    \n    export default function Component() {\n        // The counter\n        const [count, setCount] = useState < number > (0)\n        // Dynamic delay\n        const [delay, setDelay] = useState < number > (1000)\n        // ON/OFF\n        const [isPlaying, setPlaying] = useState < boolean > (false)\n        useInterval(\n            () => {\n                // Your custom logic here\n                setCount(count + 1)\n            },\n            // Delay in milliseconds or null to stop it\n            isPlaying ? delay : null,\n        )\n        const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n            setDelay(Number(event.target.value))\n        }\n        return (\n            <>\n                <h1>{count}</h1>\n                <button onClick={() => setPlaying(!isPlaying)}>\n                    {isPlaying ? 'pause' : 'play'}\n                </button>\n                <p>\n                    <label>Delay: </label>\n                    <input type=\"number\" onChange={handleChange} value={delay}/>\n                </p>\n            </>\n        )\n    }\n```\n\n### useIsClient\n\nThis react hook is very simple but it is useful. Indeed, if you manually do a typeof window! ==\" undefined \" type check,\nthen your function will be escaped, but it will stop there. Thanks to this hook, there will be a first render where\nisClient will be false, then when the window is ready, the useEffect will be executed, will update the value of isClient\nand restart your component with the window defined.\n\n```jsx\n    export default function Component() {\n        const isClient = useIsClient()\n    \n        return <div>{isClient ? 'Client' : 'server'}</div>\n    }\n```\n\n### useIsFirstRender\n\nThis hook returns true at mount time and false after that\n\n```typescript jsx\n    import React, { useEffect, useState } from 'react'\n    import { useIsFirstRender } from 'react-util-hooks'\n    \n    export default function Component() {\n        const isFirst = useIsFirstRender()\n        const [data, setData] = useState<number>(0)\n    \n        useEffect(() => {\n            console.log('Normal useEffect', { data })\n        }, [data])\n    \n        return (\n            <div>\n                <p>Open your console</p>\n                <p>Is first render: {isFirst ? 'yes' : 'no'}</p>\n                <button onClick={() => setData(Date.now())}>Update data</button>\n            </div>\n        )\n    }\n```\n\n### useKeyPress\n\nThis hook makes it easy to detect when the user is pressing a specific key on their keyboard. The recipe is fairly\nsimple, as I want to show how little code is required, but I challenge any readers to create a more advanced version of\nthis hook. Detecting when multiple keys are held down at the same time would be a nice addition. Bonus points: also\nrequire they be held down in a specified order. Feel free to share anything you've created in\nthis [recipe's gist](https://gist.github.com/gragland/b61b8f46114edbcf2a9e4bd5eb9f47f5)\n\n```jsx\n    function App() {\n        // Call our hook for each key that we'd like to monitor\n        const happyPress = useKeyPress(\"h\")\n        const sadPress = useKeyPress(\"s\")\n        const robotPress = useKeyPress(\"r\")\n        const foxPress = useKeyPress(\"f\")\n        return (\n            <div>\n                <div>h, s, r, f</div>\n                <div>\n                    {happyPress && \"😊\"}\n                    {sadPress && \"😢\"}\n                    {robotPress && \"🤖\"}\n                    {foxPress && \"🦊\"}\n                </div>\n            </div>\n        )\n    }\n```\n\n### useLocalStorage\n\nPersist the state with local storage so that it remains after a page refresh. This can be useful for a dark theme or to\nrecord session information. This hook is used in the same way as useState except that you must pass the storage key in\nthe 1st parameter. If the window object is not present (as in SSR), ```useLocalStorage()``` will return the default\nvalue\n\n```jsx\n    export default function Component() {\n        const [isDarkTheme, setDarkTheme] = useLocalStorage('darkTheme', true)\n    \n        const toggleTheme = () => {\n            setDarkTheme(!isDarkTheme)\n        }\n    \n        return (\n            <button onClick={toggleTheme}>\n                {`The current theme is ${isDarkTheme ? `dark` : `light`}`}\n            </button>\n        )\n}\n```\n\n### useLockedBody\n\nThis React hook is used to block the scrolling of the page. A good example of a use case is when you need to open a\nmodal. For flexibility, this hook offers 2 APIs:\n\nUse it as we would use a useState (example 1)\n\nUse it with our own logic, coming from a props or redux for example (example 2)\n\nFinally, you can optionally change the reflow padding if you have another sidebar size than the default (15px)\n\n```jsx\n    const fixedCenterStyle: CSSProperties = {\n        position: 'fixed',\n        top: '50%',\n        left: '50%',\n        transform: 'translate(-50%, -50%)',\n    }\n    \n    // Example 1: useLockedBody as useState()\n    export function Component1() {\n        const [locked, setLocked] = useLockedBody()\n        const toggleLocked = () => {\n            setLocked(!locked)\n        }\n        return (\n            <>\n                <div style={{minHeight: '200vh'}}/>\n                <button style={fixedCenterStyle} onClick={toggleLocked}>\n                    {locked ? 'unlock scroll' : 'lock scroll'}\n                </button>\n            </>\n        )\n    }\n    \n    // Example 2: useLockedBody with our custom state\n    export function Component2() {\n        const [locked, setLocked] = useState(false)\n        const toggleLocked = () => {\n            setLocked(!locked)\n        }\n        useLockedBody(locked)\n        return (\n            <>\n                <div style={{minHeight: '200vh'}}/>\n                <button style={fixedCenterStyle} onClick={toggleLocked}>\n                    {locked ? 'unlock scroll' : 'lock scroll'}\n                </button>\n            </>\n        )\n    }\n```\n\n### useMedia\n\nThis hook makes it super easy to utilize media queries in your component logic. In our example below we render a\ndifferent number of columns depending on which media query matches the current screen width, and then distribute images\namongst the columns in a way that limits column height difference (we don't want one column way longer than the rest).\nYou could create a hook that directly measures screen width instead of using media queries, but this method is nice\nbecause it makes it easy to share media queries between JS and your stylesheet. See it in action in\nthe [CodeSandbox Demo](https://codesandbox.io/s/6jlmpjq9vw).\n\n```jsx\n    function App() {\n        const columnCount = useMedia(\n            // Media queries\n            [\"(min-width: 1500px)\", \"(min-width: 1000px)\", \"(min-width: 600px)\"],\n            // Column counts (relates to above media queries by array index)\n            [5, 4, 3],\n            // Default column count\n            2\n        );\n        // Create array of column heights (start at 0)\n        let columnHeights = new Array(columnCount).fill(0);\n        // Create array of arrays that will hold each column's items\n        let columns = new Array(columnCount).fill().map(() => []);\n        data.forEach((item) => {\n            // Get index of shortest column\n            const shortColumnIndex = columnHeights.indexOf(Math.min(...columnHeights));\n            // Add item\n            columns[shortColumnIndex].push(item);\n            // Update height\n            columnHeights[shortColumnIndex] += item.height;\n        });\n        // Render columns and items\n        return (\n            <div className=\"App\">\n                <div className=\"columns is-mobile\">\n                    {columns.map((column) => (\n                        <div className=\"column\">\n                            {column.map((item) => (\n                                <div\n                                    className=\"image-container\"\n                                    style={{\n                                        // Size image container to aspect ratio of image\n                                        paddingTop: (item.height / item.width) * 100 + \"%\",\n                                    }}\n                                >\n                                    <img src={item.image} alt=\"\"/>\n                                </div>\n                            ))}\n                        </div>\n                    ))}\n                </div>\n            </div>\n        );\n    }\n```\n\n### useOnClickOutside\n\nReact hook for listening for clicks outside a specified element (see useRef). This can be useful for closing a modal, a\ndropdown menu etc.\n\n```jsx\n    export default function Component() {\n        const ref = useRef(null)\n    \n        const handleClickOutside = () => {\n            // Your custom logic here\n            console.log('clicked outside')\n        }\n    \n        const handleClickInside = () => {\n            // Your custom logic here\n            console.log('clicked inside')\n        }\n    \n        useOnClickOutside(ref, handleClickOutside)\n    \n        return (\n            <div\n                ref={ref}\n                onClick={handleClickInside}\n                style={{width: 200, height: 200, background: 'cyan'}}\n            />\n        )\n    }\n```\n\n### useOnScreen\n\nThis hook allows you to easily detect when an element is visible on the screen as well as specify how much of the\nelement should be visible before being considered on screen. Perfect for lazy loading images or triggering animations\nwhen the user has scrolled down to a particular section.\n\n```jsx\n    function App() {\n        // Ref for the element that we want to detect whether on screen\n        const ref = useRef();\n        // Call the hook passing in ref and root margin\n        // In this case it would only be considered onScreen if more ...\n        // ... than 300px of element is visible.\n        const onScreen = useOnScreen(ref, \"-300px\");\n        return (\n            <div>\n                <div style={{height: \"100vh\"}}>\n                    <h1>Scroll down to next section 👇</h1>\n                </div>\n                <div\n                    ref={ref}\n                    style={{\n                        height: \"100vh\",\n                        backgroundColor: onScreen ? \"#23cebd\" : \"#efefef\",\n                    }}\n                >\n                    {onScreen ? (\n                        <div>\n                            <h1>Hey I'm on the screen</h1>\n                            <img src=\"https://i.giphy.com/media/ASd0Ukj0y3qMM/giphy.gif\"/>\n                        </div>\n                    ) : (\n                        <h1>Scroll down 300px from the top of this section 👇</h1>\n                    )}\n                </div>\n            </div>\n        );\n    }\n```\n\n### usePrevious\n\nOne question that comes up a lot is \"When using hooks how do I get the previous value of props or state?\". With React\nclass components you have the componentDidUpdate method which receives previous props and state as arguments or you can\nupdate an instance variable (this.previous = value) and reference it later to get the previous value. So how can we do\nthis inside a functional component that doesn't have lifecycle methods or an instance to store values on? Hooks to the\nrescue! We can create a custom hook that uses the useRef hook internally for storing the previous value. See the recipe\nbelow with inline comments. You can also find this example in the\nofficial [React Hooks FAQ](https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state)\n\n```jsx\n    function App() {\n        // State value and setter for our example\n        const [count, setCount] = useState(0);\n        // Get the previous value (was passed into hook on last render)\n        const prevCount = usePrevious(count);\n        // Display both current and previous count value\n        return (\n            <div>\n                <h1>\n                    Now: {count}, before: {prevCount}\n                </h1>\n                <button onClick={() => setCount(count + 1)}>Increment</button>\n            </div>\n        );\n    }\n```\n\n### useReadLocalStorage\n\nThis React Hook allows you to read a value from localStorage by its key.\nIt can be useful if you just want to read without passing a default value.\nIf the window object is not present (as in SSR), or if the value doesn't exist,\nuseLocalStorage() will return null.\n\n```\n    export default function Component() {\n      // Assuming a value was set in localStorage with this key\n      const darkMode = useReadLocalStorage('darkMode')\n    \n      return <p>DarkMode is {darkMode ? 'enabled' : 'disabled'}</p>\n    }\n```\n\nNote: If you want to be able to change the value, look [useLocalStorage()](uselocalstorage)\n\n### useScreen\n\nEasily retrieve window.screen object with this Hook React which also works onRezise.\n\n```jsx\n    export default function Component() {\n        const screen = useScreen()\n    \n        return (\n            <div>\n                The current window dimensions are:{' '}\n                <code>\n                    {JSON.stringify({width: screen?.width, height: screen?.height})}\n                </code>\n            </div>\n        )\n    }\n```\n\n### useScript\n\nDynamically load an external script in one line with this React hook. This can be useful to integrate a third party\nlibrary like Google Analytics or Stripe. This avoids loading this script in the head tag on all your pages if it is not\nnecessary.\n\n```jsx\n    // it's an example, use your types instead\n    // declare const jQuery: any\n    export default function Component() {\n        // Load the script asynchronously\n        const status = useScript(`https://code.jquery.com/jquery-3.5.1.min.js`)\n    \n        useEffect(() => {\n            if (typeof jQuery !== 'undefined') {\n                // jQuery is loaded => print the version\n                alert(jQuery.fn.jquery)\n            }\n        }, [status])\n    \n        return (\n            <div>\n                <p>{`Current status: ${status}`}</p>\n    \n                {status === 'ready' && <p>You can use the script here.</p>}\n            </div>\n        )\n    }\n```\n\n### useSessionStorage\n\nThis hook saves the data in memory, kind of like localstorage but this time it saves the data in the session and browser\ndeletes the session if you close the browser or even the tab. You have to save string value in the session storage. If\nyou want to save an object, checkout [useSessionStorageWithObject](#usesessionstoragewithobject) instead\n\n```jsx\n    function App() {\n        const [item, setItem] = useSessionStorage('name', 'Initial Value');\n        return (\n            <div className=\"App\">\n                <h1>Set Name to store in Local Storage</h1>\n                <div>\n                    <label>\n                        Name:{' '}\n                        <input\n                            type=\"text\"\n                            placeholder=\"Enter your name\"\n                            value={item}\n                            onChange={e => setItem(e.target.value)}\n                        />\n                    </label>\n                </div>\n            </div>\n        );\n    }\n```\n\n### useSessionStorageWithObject\n\nThis hook actually uses [useSessionStorage](#usesessionstorage). But it takes an object and stringify it and then save\nit. It also parses the data when fetching from the browser, so you can use it like a regular object.\n\n```jsx\n    function App() {\n        const [form, setForm] = useSessionStorage < {email: string, name: string} > ('name', {name: '', email: ''});\n        return (\n            <div className=\"App\">\n                <h1>Set Name to store in Local Storage</h1>\n                <div>\n                    <label>\n                        Name:{' '}\n                        <input\n                            type=\"text\"\n                            placeholder=\"Enter your name\"\n                            value={form.name}\n                            onChange={e => setForm({...form, name: e.target.value})}\n                        />\n                    </label>\n                </div>\n                <div>\n                    <label>\n                        Name:{' '}\n                        <input\n                            type=\"text\"\n                            placeholder=\"Enter your email\"\n                            value={form.email}\n                            onChange={e => setItem({...form, email: e.target.value})}\n                        />\n                    </label>\n                </div>\n            </div>\n        );\n    }\n```\n\n### useUpdateEffect\n\nThis hook is just the modified version of useEffect that is skipping the first render.\n\n```typescript jsx\n    import React, { useEffect, useState } from 'react'\n    import { useUpdateEffect } from 'react-util-hooks'\n    \n    export default function Component() {\n      const [data, setData] = useState<number>(0)\n      useEffect(() => {\n        console.log('Normal useEffect', { data })\n      }, [data])\n    \n      useUpdateEffect(() => {\n        console.log('Update useEffect only', { data })\n      }, [data])\n    \n      return (\n        <div>\n          <p>Open your console</p>\n          <button onClick={() => setData(Date.now())}>Update data</button>\n        </div>\n      )\n    }\n```\n\n### useTimeout\n\nVery similar to the [useInterval](https://usehooks-typescript.com/react-hook/use-interval) hook, this React hook\nimplements the native setTimeout function keeping the same interface. You can enable the timeout by setting delay as a\nnumber or disabling it using null. When the time finish, the callback function called.\n\n```jsx\n    export default function Component() {\n        const [visible, setVisible] = useState(true)\n        const hide = () => setVisible(false)\n        useTimeout(hide, 5000)\n        return (\n            <div>\n                <p>\n                    {visible\n                        ? \"I'm visible for 5000ms\"\n                        : 'You can no longer see this content'}\n                </p>\n            </div>\n        )\n    }\n```\n\n### useSsr\n\nQuickly know where your code will be executed;\n\n- In the server (Server-Side-Rendering) or\n- In the client, the navigator\n\nThis hook doesn't cause an extra render, it just returns the value directly, at the mount time,\nand it didn't re-trigger if the value changes.\n\nOtherwise, If you want to be notified when the value changes to react to it,\nyou can use [useIsClient()](useisclient) instead.\n\n```\n    export default function Component() {\n      const { isBrowser } = useSsr()\n    \n      return <p>{isBrowser ? 'Browser' : 'Server'}!</p>\n    }\n```\n\n### useToggle\n\nBasically, what this hook does is that, it takes a parameter with value true or false and toggles that value to\nopposite. It's useful when we want to take some action into it's opposite action, for example: show and hide modal, show\nmore/show less text, open/close side menu.\n\n```jsx\n    function App() {\n        // Call the hook which returns, current value and the toggler function\n        const [isTextChanged, setIsTextChanged] = useToggle();\n    \n        return (\n            <button onClick={setIsTextChanged}>{isTextChanged ? 'Toggled' : 'Click to Toggle'}</button>\n        );\n    }\n```\n\n### useWindowSize\n\nEasily retrieve window dimensions with this Hook React which also works onRezise.\n\n```jsx\n    export default function Component() {\n        const {width, height} = useWindowSize()\n    \n        return (\n            <div>\n                The current window dimensions are:{' '}\n                <code>{JSON.stringify({width, height})}</code>\n            </div>\n        )\n    }\n```\n\n## Project status\n\nI created this library because I needed it. Feel free to use it and give feedbacks.\n\nYou can also create hooks and send PR, thanks.\n\nIf you find any bugs or have new hook ideas, [create an issue](https://github.com/prantaDutta/react-util-hooks/issues).\n\n## Support Me\n\nBecome a [Patreon](https://www.patreon.com/prantadutta) 🥰👋\n\n## References\n\n- https://usehooks-typescript.com/\n- https://usehooks.com/","readmeFilename":"README.md"}