├── README.md
├── hooks.md
├── hooks
├── useBase64Encode.jsx
├── useClickInside.jsx
├── useClickOutside.jsx
├── useCopyToClipBoard.jsx
├── useCounter.jsx
├── useDialog.jsx
├── useFetch.jsx
├── useFileUpload.js
├── useHoverEvent.jsx
├── useHoverIn.jsx
├── useHoverOut.jsx
├── useInputField.jsx
├── useLocalStorage.js
├── usePagination.jsx
├── usePrevious.jsx
├── useSearchHook.js
├── useSecondsTimer.jsx
├── useSelectedList.jsx
├── useTimer.jsx
├── useToggle.jsx
└── useUpdateEffect.jsx
├── index.js
└── refer.md
/README.md:
--------------------------------------------------------------------------------
1 | # react-custom-hooks
2 | Custom hooks in React.js that are handy in daily day to day code
3 |
4 | ##
5 |
6 | #### Custom Hooks
7 |
8 | - [useCounter](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useCounter.jsx) - React Hook to handle counter, increment and decrement
9 | - [useDialog](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useDialog.jsx) - React Hook to handle open and close dialogs
10 | - [useFetch](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useFetch.jsx) - React Hook to call apis on load with Fetch
11 | - [usePrevious](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/usePrevious.jsx) - React Hook to use previos state and props
12 | - [useToggle](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useToggle.jsx) - React Hook to handle toggle button and lists
13 | - [useInputField](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useInputField.jsx) - React Hook to use state values for input fields
14 | - [useUpdateEffect](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useClickOutside.jsx) - React Hook to call snippet ONLY-ON-UPDATE
15 | - [useCopyToClipBoard](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useCopyToClipBoard.jsx) - When you want to pass a state value and provide a copy to ClipBoard option
16 | - [useBase64Encode](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useBase64Encode.jsx) - React Hook to encode event String value to Base64 without storing text anywhere
17 | - [useSecondsTimer](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useSecondsTimer.jsx) - React Hook to use timer from n to 0 seconds
18 | - [useTimer](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useTimer.jsx) - React Hook to use timer from 0 to hh:mm:ss time runner until stopped.
19 | - [useClickInside](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useClickInside.jsx) - When you want to call a function when clicked inside the element Ex: Modal PopUp
20 | - [useClickOutside](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useClickOutside.jsx) - When you want to call a function when clicked outside the element Ex: Modal PopUp
21 | - [useHoverIn](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useHoverIn.jsx) - When you want to call a function when hovered or mouse over inside the element Ex: hovering a menu or enabling shopping card zoom
22 | - [useHoverOut](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useHoverOut.jsx) - When you want to call a function when hovered or mouse out outside the element Ex: hovering out of a menu or disabling shopping card zoom
23 | - [useHoverEvent](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useHoverEvent.jsx) - When you want to call a function when hovered or mouse out inside and outside the element Ex: hovering out of a menu or disabling shopping card zoom.
24 | [useHoverEvent](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useHoverEvent.js) hook has both [useHoverIn](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useHoverIn.js) and [useHoverOut](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/useHoverOut.js) events
25 | - [usePagination](https://github.com/sarat9/react-custom-hooks/blob/master/hooks/usePagination.jsx) - React Hook to handle numerical paginations
26 |
27 | ##
28 | ##
29 |
30 |
31 | #### Other External Hook Libraries
32 | - [awesome-react-hooks](https://github.com/glauberfc/awesome-react-hooks) - A curated list about React Hooks.
33 | - [react-use](https://github.com/streamich/react-use) - Library with Collection of essential hooks
34 | - [react-hook-form](https://github.com/react-hook-form/react-hook-form) - Handling Forms with Performant, flexible and extensible forms with easy-to-use validation.
35 | ##
36 | ##
37 |
38 |
39 |
40 | # React Hooks!
41 |
42 |
43 | ##
44 | ##
45 |
46 | #### Things To take care while creating Hooks!
47 | - **Handle Memory Leaks** : The memory leak will happen if the API server or host took some time to respond and the component was unmounted before the response was received. Though the component was unmounted, the response to the request will still be received on completion. The response will then be parsed and setData will be called.
48 |
49 | -> [How To Fix Memory Leak Issue In React Js Using Hook](https://medium.com/wesionary-team/how-to-fix-memory-leak-issue-in-react-js-using-hook-a5ecbf9becf8)
50 |
51 |
52 |
53 |
54 | ##
55 | ##
56 |
57 |
58 |
59 |
60 | [](https://github.com/sarat9/)
61 |
--------------------------------------------------------------------------------
/hooks.md:
--------------------------------------------------------------------------------
1 |
2 | Custom React Hooks Handy
3 |
4 | HOOKS:
5 |
6 | Abstract logic to Hooks.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Npm Libraries:
18 |
19 |
20 |
--------------------------------------------------------------------------------
/hooks/useBase64Encode.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react'
2 |
3 | /**
4 | * @function useBase64Encode
5 | * @description React Hook to encode event String value to Base64 without storing text anywhere
6 | * @param {any} value
7 | * @returns {any} encoded value and function to pass event
8 | * @author Sarat Chandra Ejjapureddi
9 | */
10 | export default function useBase64Encode(defaultValue = '') {
11 | const [value, setValue] = useState(btoa(defaultValue))
12 |
13 | const encodeValue = (e) => {
14 | if (e) {
15 | // btoa() Encodes String to Base64
16 | setValue(btoa(e.target.value))
17 | }
18 | }
19 |
20 | const decodeValue = (e) => {
21 | if (e) {
22 | // atob() Encodes Base64 to String
23 | setValue(atob(e.target.value))
24 | }
25 | }
26 | return [value, encodeValue]
27 | }
28 |
29 |
30 |
31 |
32 |
33 |
34 | /*
35 | * What is Base64?
36 | * https://infosecwriteups.com/base64-explained-17cd8864da02
37 | */
38 |
--------------------------------------------------------------------------------
/hooks/useClickInside.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from '../../../../../Users/scejjapu/AppData/Local/Microsoft/TypeScript/2.9/node_modules/@types/react'
2 |
3 |
4 |
5 | /**
6 | * @function useClickInside
7 | * @param {any} elementRef
8 | * @param {any} callback
9 | * @returns {any}
10 | * @description When you want to call a function when clicked inside the element Ex: Modal PopUp
11 | * Pass the callback with useCallBack in your function since it's functionality always remains same for better performance.
12 | * @author Sarat Chandra Ejjapureddi
13 | */
14 | export default function useClickInside(elementRef, callback) {
15 | React.useEffect(() => {
16 | const handleClickInside = (event) => {
17 | event.preventDefault()
18 | if (elementRef && elementRef.current && elementRef.current.contains(event.target)) {
19 | // Call Callback only if event happens inside element or descendent elements
20 | callback()
21 | }
22 | return
23 | }
24 | document.addEventListener('click', handleClickInside, true)
25 | return () => {
26 | document.removeEventListener('click', handleClickInside, true)
27 | }
28 | }, [elementRef, callback])
29 | }
30 |
31 |
32 | /**
33 | * @function useClickInside
34 | * @param {any} elementRef
35 | * @param {any} callback
36 | * @returns {any}
37 | * @description When you want to call a function when clicked inside the element Ex: Modal PopUp
38 | * Use this function rather than above when you are sure you wont be changing the callback.
39 | * You then don't need to pass the callback with useCallback for performance.
40 | */
41 | export function useClickInside2(elementRef, callback) {
42 | const callbackRef = useRef(callback)
43 | React.useEffect(() => {
44 | const handleClickInside = (event) => {
45 | event.preventDefault()
46 | if (elementRef && elementRef.current && elementRef.current.contains(event.target)) {
47 | // Call Callback only if event happens inside element or descendent elements
48 | callbackRef.current()
49 | }
50 | return
51 | }
52 | document.addEventListener('click', handleClickInside, true)
53 | return () => {
54 | document.removeEventListener('click', handleClickinside, true)
55 | }
56 | }, [elementRef, callback])
57 | }
--------------------------------------------------------------------------------
/hooks/useClickOutside.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 |
4 |
5 | /**
6 | * @function useClickOutside
7 | * @param {any} elementRef
8 | * @param {any} callback
9 | * @returns {any}
10 | * @description When you want to call a function when clicked outside the element Ex: Modal PopUp
11 | * @author Sarat Chandra Ejjapureddi
12 | * Pass the callback with useCallBack in your function since it's functionality always remains same for better performance.
13 | */
14 | export default function useClickOutside(elementRef, callback) {
15 | React.useEffect(() => {
16 | const handleClickOutside = (event) => {
17 | event.preventDefault()
18 | if (elementRef && elementRef.current && !elementRef.current.contains(event.target)) {
19 | // Call Callback only if event happens outside element or descendent elements
20 | callback()
21 | }
22 | return
23 | }
24 | document.addEventListener('click', handleClickOutside, true)
25 | return () => {
26 | document.removeEventListener('click', handleClickOutside, true)
27 | }
28 | }, [elementRef, callback])
29 | }
30 |
31 |
32 | /**
33 | * @function useClickOutside
34 | * @param {any} elementRef
35 | * @param {any} callback
36 | * @returns {any}
37 | * @description When you want to call a function when clicked outside the element Ex: Modal PopUp
38 | * Use this function rather than above when you are sure you wont be changing the callback.
39 | * You then don't need to pass the callback with useCallback for performance.
40 | */
41 | export function useClickOutside2(elementRef, callback) {
42 | const callbackRef = useRef(callback)
43 | React.useEffect(() => {
44 | const handleClickOutside = (event) => {
45 | event.preventDefault()
46 | if (elementRef && elementRef.current && !elementRef.current.contains(event.target)) {
47 | // Call Callback only if event happens outside element or descendent elements
48 | callbackRef.current()
49 | }
50 | return
51 | }
52 | document.addEventListener('click', handleClickOutside, true)
53 | return () => {
54 | document.removeEventListener('click', handleClickOutside, true)
55 | }
56 | }, [elementRef, callback])
57 | }
--------------------------------------------------------------------------------
/hooks/useCopyToClipBoard.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 |
4 |
5 | /**
6 | * @function useCopyToClipboard
7 | * @param {any} text
8 | * @returns {[Function, Function]}
9 | * @description When you want to pass a state value and provide a copy to ClipBoard option
10 | * @author Sarat Chandra Ejjapureddi
11 | *
12 | * When you want to pass a state value and provide a copy to ClipBoard option.
13 | * Whenever a state value is passed as parameter, invoking the call function will set the value in clipboard
14 | */
15 | export default function useCopyToClipboard(text) {
16 |
17 | const copyToClipboard = (str) => {
18 | const el = document.createElement('textarea');
19 | el.value = str;
20 | el.setAttribute('readonly', '');
21 | el.style.position = 'absolute';
22 | el.style.left = '-9999px';
23 | document.body.appendChild(el);
24 | const selected =
25 | document.getSelection().rangeCount > 0
26 | ? document.getSelection().getRangeAt(0)
27 | : false;
28 | el.select();
29 | const success = document.execCommand('copy');
30 | document.body.removeChild(el);
31 | if (selected) {
32 | document.getSelection().removeAllRanges();
33 | document.getSelection().addRange(selected);
34 | }
35 | return success;
36 | };
37 |
38 | const [copied, setCopied] = React.useState(false);
39 |
40 | const copy = React.useCallback(() => {
41 | if (!copied) setCopied(copyToClipboard(text));
42 | }, [text]);
43 |
44 | React.useEffect(() => () => setCopied(false), [text]);
45 |
46 | return [copied, copy];
47 | };
--------------------------------------------------------------------------------
/hooks/useCounter.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 |
3 |
4 | /**
5 | * @function useCounter
6 | * @description React Hook to handle counter, increment and decrement
7 | * @returns {Array:Function} : [counter, increment, decrement]
8 | * @author Sarat Chandra Ejjapureddi
9 | */
10 | function useCounter(defaultValue=0) {
11 | const [counter, setCounter] = React.useState(defaultValue);
12 |
13 | const increment = () => {
14 | setCounter(counter+1);
15 | };
16 |
17 | const decrement = () => {
18 | setCounter(counter-1);
19 | };
20 | return [counter, increment, decrement]
21 | }
22 |
23 | export default useCounter
--------------------------------------------------------------------------------
/hooks/useDialog.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 |
3 |
4 | /**
5 | * @function useDialogHook
6 | * @description React Hook to handle open and close dialogs
7 | * @returns {Array:Function} : [open, handleClickOpen, handleClose]
8 | * @author Sarat Chandra Ejjapureddi
9 | */
10 | function useDialogHook() {
11 | const [open, setOpen] = React.useState(false);
12 |
13 | const handleClickOpen = () => {
14 | setOpen(true);
15 | };
16 |
17 | const handleClose = () => {
18 | setOpen(false);
19 | };
20 | return [open, handleClickOpen, handleClose]
21 | }
22 |
23 | export default useDialogHook
--------------------------------------------------------------------------------
/hooks/useFetch.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 |
4 |
5 | const initialOptions = {
6 | method: 'GET', // *GET, POST, PUT, DELETE, etc.
7 | mode: 'cors', // no-cors, *cors, same-origin
8 | cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
9 | credentials: 'same-origin', // include, *same-origin, omit
10 | headers: {
11 | 'Content-Type': 'application/json'
12 | // 'Content-Type': 'application/x-www-form-urlencoded',
13 | },
14 | redirect: 'follow', // manual, *follow, error
15 | referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
16 | // body: JSON.stringify(data) // body data type must match "Content-Type" header
17 | };
18 |
19 | /**
20 | * @function useFetch
21 | * @description React Hook to call apis on load with Fetch .
22 | * componentMounted flag to avaoid memory leak
23 | * @param {string} url
24 | * @param {Object} options
25 | * @returns {Object} { response, error, loading }
26 | * @author Sarat Chandra Ejjapureddi
27 | * @example data = useFetch('')
28 | */
29 | export default function useFetch(url, options = initialOptions) {
30 | const [response, setResponse] = useState(null)
31 | const [error, setError] = useState(null)
32 | const [loading, setLoading] = useState(false)
33 | useEffect(() => {
34 | let componentMounted = true;
35 | const fetchData = async () => {
36 |
37 | try {
38 | setLoading(true)
39 | const res = await fetch(url, options)
40 | const json = await res.json()
41 | if(componentMounted){
42 | setResponse(json)
43 | }
44 | } catch (err) {
45 | setLoading(false)
46 | setError(err)
47 | }
48 | finally {
49 | setLoading(false)
50 | }
51 | }
52 | fetchData()
53 | return () => {
54 | componentMounted = false;
55 | }
56 | }, [])
57 | return { response, error, loading }
58 | }
--------------------------------------------------------------------------------
/hooks/useFileUpload.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react'
2 |
3 | /**
4 | * @function useFileUpload
5 | * @description React Hook to use state values for file uploads
6 | * @returns [selectedFile, handleFileInputChange, fileDetails]
7 | * @author Sarat Chandra Ejjapureddi
8 | */
9 | export default function useFileUpload() {
10 | const [selectedFile, setSelectedFile] = useState(null);
11 | const [fileDetails, setFileDetails] = useState(null);
12 |
13 |
14 | const handleFileInputChange = (e) => {
15 | const fileData = e.target.files[0];
16 | const { name, type, size } = fileData;
17 | setSelectedFile(fileData);
18 | setFileDetails({ name, type, size });
19 | };
20 |
21 | return [selectedFile, handleFileInputChange, fileDetails]
22 | }
--------------------------------------------------------------------------------
/hooks/useHoverEvent.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 |
4 |
5 | /**
6 | * @function useHoverEvent
7 | * @param {any} elementRef
8 | * @param {any} hoveredCallback - when hovered on element
9 | * @param {any} hoveredOutCallback - when hovered/mouse out from the element after hover
10 | * @returns {any}
11 | * @description When you want to call a function when hovered inside the element
12 | * Ex: Hovering on Shopping Card should detect the event call a function to scroll other pics or highlighting
13 | * Pass the callback with useCallBack in your function since it's functionality always remains same for better performance.
14 | * @author Sarat Chandra Ejjapureddi
15 | */
16 | export default function useHoverEvent(elementRef, hoveredCallback, hoveredOutCallback) {
17 | React.useEffect(() => {
18 | const handleHoverInside = (event) => {
19 | event.preventDefault()
20 | if (elementRef && elementRef.current && elementRef.current.contains(event.target)) {
21 | // Call Callback only if event happens inside element or descendent elements
22 | hoveredCallback()
23 | }
24 | return
25 | }
26 | const handleHoverOut = (event) => {
27 | event.preventDefault()
28 | if (elementRef && elementRef.current && elementRef.current.contains(event.target)) {
29 | // Call Callback only if event happens inside element or descendent elements
30 | hoveredOutCallback()
31 | }
32 | return
33 | }
34 |
35 | // Calls when an elements is hovered
36 | document.addEventListener('mouseover', handleHoverInside, true)
37 | // Calls when an elements is hovered and then hovered out (mouseout) of that element
38 | document.addEventListener('mouseout', handleHoverOut, true)
39 | return () => {
40 | document.removeEventListener('mouseover', handleHoverInside, true)
41 | document.removeEventListener('mouseout', handleHoverOut, true)
42 | }
43 | }, [elementRef, hoveredCallback, hoveredOutCallback])
44 | }
--------------------------------------------------------------------------------
/hooks/useHoverIn.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 |
4 |
5 | /**
6 | * @function useHoverIn
7 | * @param {any} elementRef
8 | * @param {any} callback
9 | * @returns {any}
10 | * @description When you want to call a function when hovered inside the element
11 | * Ex: Hovering on Shopping Card should detect the event call a function to scroll other pics or highlighting
12 | * Pass the callback with useCallBack in your function since it's functionality always remains same for better performance.
13 | * @author Sarat Chandra Ejjapureddi
14 | */
15 | export default function useHoverIn(elementRef, callback) {
16 | React.useEffect(() => {
17 | const handleHoverInside = (event) => {
18 | event.preventDefault()
19 | if (elementRef && elementRef.current && elementRef.current.contains(event.target)) {
20 | // Call Callback only if event happens inside element or descendent elements
21 | callback()
22 | }
23 | return
24 | }
25 | document.addEventListener('mouseover', handleHoverInside, true)
26 | return () => {
27 | document.removeEventListener('mouseover', handleHoverInside, true)
28 | }
29 | }, [elementRef, callback])
30 | }
--------------------------------------------------------------------------------
/hooks/useHoverOut.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 | /**
4 | * @function useHoverOut
5 | * @param {any} elementRef
6 | * @param {any} callback
7 | * @returns {any}
8 | * @description When you want to call a function when hovered inside the element
9 | * Ex: Hovering on Shopping Card should detect the event call a function to scroll other pics or highlighting
10 | * Pass the callback with useCallBack in your function since it's functionality always remains same for better performance.
11 | * @author Sarat Chandra Ejjapureddi
12 | */
13 | export default function useHoverOut(elementRef, callback) {
14 | React.useEffect(() => {
15 | const handleHoverOut = (event) => {
16 | event.preventDefault()
17 | if (elementRef && elementRef.current && elementRef.current.contains(event.target)) {
18 | // Call Callback only if event happens inside element or descendent elements
19 | callback()
20 | }
21 | return
22 | }
23 | document.addEventListener('mouseout', handleHoverOut, true)
24 | return () => {
25 | document.removeEventListener('mouseout', handleHoverOut, true)
26 | }
27 | }, [elementRef, callback])
28 | }
--------------------------------------------------------------------------------
/hooks/useInputField.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react'
2 |
3 | /**
4 | * @function useInputField
5 | * @description React Hook to use state values for input fields
6 | * @param {any} defaultValue
7 | * @param {boolean} specialCharsAllow
8 | * @returns {any}
9 | * @author Sarat Chandra Ejjapureddi
10 | */
11 | export default function useInputField(defaultValue = '', specialCharsAllow=true) {
12 | const [value, setValue] = useState(defaultValue)
13 |
14 | const handleInputValue = (e) => {
15 | if (e) {
16 | let val = e.target.value
17 | if(!specialCharsAllow){
18 | val = val.replace(/[^\w\s]/gi, "")
19 | }
20 | setValue(e.target.value)
21 | }
22 | }
23 |
24 | return [value, setValue, handleInputValue]
25 | }
26 |
27 |
28 |
29 | // Regex Expressions to handle Special Characters depending o n UseCase
30 | /*
31 | * Replaces all Special Characters:
32 | * val.replace(/[^\w\s]/gi, "")
33 | * Replaces all Special Characters Except Comma(,):
34 | * val.replace(/[^\w\s,]/gi, "")
35 | * Allows only Numeric Digits and Comma(,):
36 | * val.replace(/[^0-9\.,]/g, "")
37 | *
38 | **/
--------------------------------------------------------------------------------
/hooks/useLocalStorage.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | // Hook to get and set values in localStorage
4 | export function useLocalStorage(key, initialValue=null) {
5 |
6 | const [storedValue, setStoredValue] = useState(() => {
7 | try {
8 | const item = window.localStorage.getItem(key);
9 | return item ? JSON.parse(item) : initialValue;
10 | } catch (error) {
11 | console.log(error);
12 | return initialValue;
13 | }
14 | });
15 |
16 | const setValue = value => {
17 | try {
18 | const valueToStore = value instanceof Function ? value(storedValue) : value;
19 | setStoredValue(valueToStore);
20 | window.localStorage.setItem(key, JSON.stringify(valueToStore));
21 | } catch (error) {
22 | console.log(error);
23 | }
24 | };
25 |
26 | return [storedValue, setValue];
27 | }
28 |
--------------------------------------------------------------------------------
/hooks/usePagination.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 |
3 |
4 | /**
5 | * @function usePagination
6 | * @description React Hook to handle page, increment, decrement and setPage
7 | * @returns {Array:Function} : [page, increment, decrement, setPage]
8 | * @author Sarat Chandra Ejjapureddi
9 | */
10 | function usePagination(defaultValue=1) {
11 | const [page, setPage] = React.useState(defaultValue);
12 |
13 | const onToNextPage = () => {
14 | setPage(page+1);
15 | };
16 |
17 | const onToPreviousPage = () => {
18 | setPage(page-1);
19 | };
20 |
21 | const handlePage = (e,value) => {
22 | e.preventDefault()
23 | setPage(value);
24 | };
25 |
26 | const resetPage = () => {
27 | setPage(defaultValue);
28 | }
29 |
30 | return [page, handlePage, resetPage, onToNextPage, onToPreviousPage, setPage]
31 | }
32 |
33 | export default usePagination
--------------------------------------------------------------------------------
/hooks/usePrevious.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 | /**
4 | * @function usePrevious
5 | * @description React Hook to use previos state and props
6 | * @param {any} value
7 | * @returns {any} previousValue
8 | * @author Sarat Chandra Ejjapureddi
9 | */
10 | export default function usePrevious(value) {
11 | const previousValue = useRef(value)
12 | useEffect(() => {
13 | previousValue.current = value;
14 | })
15 |
16 | // Return previous value (happens before update in useEffect above)
17 | return previousValue.current
18 | }
--------------------------------------------------------------------------------
/hooks/useSearchHook.js:
--------------------------------------------------------------------------------
1 | import { func } from "prop-types";
2 | import React, { useState, useEffect, useCallback, useRef } from "react";
3 |
4 | /**
5 | * @function useSearch
6 | * @description React Hook to use state values for input fields
7 | * @param {any} defaultValue
8 | * @param {int} debounceDelay
9 | * @returns {any}
10 | * @author Sarat Chandra Ejjapureddi
11 | */
12 | export default function useSearch(defaultValue = "", debounceDelay = 500) {
13 | const [value, setValue] = useState(defaultValue);
14 |
15 | const handleInputValue = (e) => {
16 | if (e) {
17 | e.preventDefault();
18 | let val = e.target.value;
19 | setValue(val);
20 | }
21 | };
22 |
23 | const debouncedFun = debounce(handleInputValue, debounceDelay);
24 | return [value, setValue, debouncedFun];
25 | }
26 |
27 |
28 | function debounce(fn, wait) {
29 | let timeout;
30 | return function () {
31 | clearTimeout(timeout);
32 | const args = arguments;
33 | timeout = setTimeout(() => {
34 | fn(...args);
35 | }, wait);
36 | };
37 | }
38 |
39 | function useDebounce(callback, delay = 500) {
40 | const debounceRef = useRef();
41 | let debouncedCallback = function(){
42 |
43 | if (debounceRef.current) {
44 | clearTimeout(debounceRef.current);
45 | }
46 |
47 | debounceRef.current = setTimeout(()=> {
48 | const args = arguments;
49 | callback(...args);
50 | }, delay);
51 | };
52 |
53 | return debouncedCallback;
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/hooks/useSecondsTimer.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react'
2 |
3 |
4 | /**
5 | * @function useSecondsTimer
6 | * @description React Hook to use timer from n to 0 seconds
7 | * @param {any} defaultClock default time to start timer
8 | * @returns {any} [time, playing, togglePlayPause, handleReset]
9 | * @author Sarat Chandra Ejjapureddi
10 | */
11 | export default function useSecondsTimer(defaultClock = 0) {
12 | const [time, setTime] = useState(defaultClock);
13 | const [playing, setPlaying] = useState(true);
14 |
15 | const tick = (e) => {
16 | e && e.preventDefault()
17 | if (time > 0 && playing) {
18 | setTime(time - 1)
19 | }
20 | }
21 |
22 | const handleReset = (e) => {
23 | e && e.preventDefault()
24 | setTime(defaultClock)
25 | }
26 |
27 | const togglePlayPause = (e) => {
28 | e && e.preventDefault()
29 | setPlaying(!playing)
30 | }
31 |
32 | useEffect(() => {
33 | let timerId = setInterval(tick, 1000);
34 | return () => clearInterval(timerId);
35 | }, [time, playing])
36 |
37 |
38 | return [time, playing, togglePlayPause, handleReset]
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/hooks/useSelectedList.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react'
2 |
3 | /**
4 | * @function useSelectedList
5 | * @description React Hook to use List where we can select or unselect list of items
6 | * @param {any} value
7 | * @returns {any}
8 | * @author Sarat Chandra Ejjapureddi
9 | */
10 | export default function useSelectedList(defaultList = [], uniqueValue) {
11 |
12 |
13 | //-------------------IN Progress
14 |
15 | const [list, setList] = useState(defaultList)
16 | const [uniqueValue, setUniqueValue] = useState(uniqueValue)
17 | const [selectedList, setSelectedList] = useState(uniqueValue)
18 |
19 |
20 |
21 |
22 | const handleInputValue = (e) => {
23 | if (e) {
24 | setValue(e.target.value)
25 | }
26 | }
27 |
28 | return [list]
29 | }
--------------------------------------------------------------------------------
/hooks/useTimer.jsx:
--------------------------------------------------------------------------------
1 |
2 | import React, { useState, useEffect } from 'react'
3 |
4 |
5 | /**
6 | * @function useTimer
7 | * @description React Hook to use timer in format hh:mm:ss
8 | * @param {any} defaultClock default time to start timer
9 | * @param {any} defaultRunningStatus default runing status of timer
10 | * @returns {any} [time, isTimerRunning, togglePlayPause, handleReset]
11 | * You can use the values timer, isTimerRunning, toggleTimer, resetTimer
12 | * @author Sarat Chandra Ejjapureddi
13 | */
14 | export default function useTimer(defaultClock = 0, defaultRunningStatus =false) {
15 | const [time, setTime] = useState(defaultClock);
16 | const [isTimerRunning, setTimerRunning] = useState(defaultRunningStatus);
17 | const [timerData, setTimerData] = useState('HH:MM:SS');
18 |
19 | const tick = (e) => {
20 | e && e.preventDefault()
21 | if (time >= 0 && isTimerRunning) {
22 | setTime(time + 1)
23 | }
24 | }
25 |
26 | const handleReset = (e) => {
27 | e && e.preventDefault()
28 | setTime(defaultClock)
29 | }
30 |
31 | const togglePlayPause = (e) => {
32 | e && e.preventDefault()
33 | setTimerRunning(!isTimerRunning)
34 | }
35 |
36 | const secondsToHMSText = (seconds) => {
37 | // Use this function if you want to get timer data in text
38 | // example - '2 hours, 44 minutes, 49 seconds'
39 | seconds = Number(seconds);
40 | var h = Math.floor(seconds / 3600);
41 | var m = Math.floor(seconds % 3600 / 60);
42 | var s = Math.floor(seconds % 3600 % 60);
43 |
44 | var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
45 | var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
46 | var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
47 | return hDisplay + mDisplay + sDisplay;
48 | }
49 |
50 | const secondsToHMS = (seconds) => {
51 | console.log(seconds)
52 | seconds = Number(seconds);
53 | var h = Math.floor(seconds / 3600);
54 | var m = Math.floor(seconds % 3600 / 60);
55 | var s = Math.floor(seconds % 3600 % 60);
56 |
57 | var hDisplay = h > 0 ? String(h).padStart(2, '0') : "00";
58 | var mDisplay = m > 0 ? String(m).padStart(2, '0') : "00";
59 | var sDisplay = s > 0 ? String(s).padStart(2, '0') : "00";
60 | // example - '2 hours, 44 minutes, 49 seconds'
61 | return hDisplay + ':' + mDisplay + ':' + sDisplay;
62 | }
63 |
64 | useEffect(() => {
65 | setTimerData(secondsToHMS(time))
66 | let timerId = setInterval(tick, 1000);
67 | return () => clearInterval(timerId);
68 | }, [time, isTimerRunning])
69 |
70 |
71 | return [timerData, isTimerRunning, togglePlayPause, handleReset]
72 | }
--------------------------------------------------------------------------------
/hooks/useToggle.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useCallback } from 'react'
2 |
3 | /**
4 | * @function useToggleHook
5 | * @description React Hook to handle toggle button and lists
6 | * @returns {Array:Function} : [open, handleClickOpen, handleClose]
7 | */
8 | function useToggle(defaultState) {
9 | const [open, setOpen] = useState(defaultState||false);
10 |
11 | const toggleFun = useCallback((e) => {
12 | setOpen(!open);
13 | e.stopPropagation();
14 | },[open]);
15 |
16 | return [open, toggleFun]
17 | }
18 |
19 | export default useToggle
--------------------------------------------------------------------------------
/hooks/useUpdateEffect.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react'
2 |
3 |
4 | /**
5 | * @function useUpdateEffect
6 | * @description React Hook to call snippet ONLY-ON-UPDATE
7 | * Refrence: https://stackoverflow.com/questions/55075604/react-hooks-useeffect-only-on-update
8 | *
9 | * @param {Function} effect
10 | * @param {Array} dependencies
11 | * @returns {Function} cleanUpFunction()
12 | * @author Sarat Chandra Ejjapureddi
13 | */
14 | export default function useUpdateEffect(effect, dependencies) {
15 | const isInitialMount = useRef(true);
16 | let cleanUpFunction = function () { }
17 | useEffect(() => {
18 | if (isInitialMount.current) {
19 | isInitialMount.current = false;
20 | } else {
21 | cleanUpFunction = effect() || cleanUpFunction
22 | }
23 | return () => {
24 | cleanUpFunction()
25 | // if (!isInitialMount.current) {
26 | // isInitialMount.current = true;
27 | // }
28 | }
29 | }, dependencies);
30 | }
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sarat9/react-custom-hooks/5c30892fe540597f1df3db43b56dc43c72dd44e8/index.js
--------------------------------------------------------------------------------
/refer.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Helpful Links:
4 |
5 | - https://usehooks.com/
6 | - https://www.30secondsofcode.org/react/t/hooks/p/1
7 | - https://github.com/beizhedenglong/react-hooks-lib
8 | - https://github.com/react-hook-form/react-hook-form
9 |
--------------------------------------------------------------------------------