paint-brush
Top 3 React Custom hooks in current projectby@rzhelieznov
1,026 reads
1,026 reads

Top 3 React Custom hooks in current project

by RomanAugust 9th, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Hook takes 2 arguments: initial value and delay in milliseconds. It can be used for example for cases when we want to send a search request for autosuggestions in fields. Hook is very small and simple: useCustomEvent = ( (Event): AppCustomEvents, (Event listener: EventListenerOrEventOrEventObject) Hook work with generics as we can work with different data types. Hook will execute on every value or delay change and return the delayed value in the target timeout.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Top 3 React Custom hooks in current project
Roman HackerNoon profile picture


Custom hooks are an amazing thing that happened with React. It brings to us the ability to create beautiful components and move a lot of business logic to hooks. Here is the list of the 3 most used custom hooks in my everyday work during the last month.

useDelay

We’re using this hook in form inputs, where we need to take the user’s inputs with some delay. It can be used for example for cases when we want to send a search request for autosuggestions in fields, but we don’t want to send requests on every input change. Instead of this, we take the input’s value with a little delay.


As usual, we started by creating an empty hook. Hook work with generics as we can work with different data types. Hook takes 2 arguments: initial value and delay in milliseconds. And we return delayValue


export const useDelay = <T>(value: T, delay: number): T => {
    const [delayValue, setDelayValue] = useState<T>(value);


    return delayValue;
};


Then we will add useEffect to wrap timeout logic. It will execute on every value or delay change and return the delayed value in the target timeout


useEffect(() => {
    const handler = setTimeout(() => {
        setDelayValue(value);
    }, delay);

    return (): void => {
        clearTimeout(handler);
    };
}, [value, delay]);


Full solution:

export const useDelay = <T>(value: T, delay: number): T => {
    const [delayValue, setDelayValue] = useState<T>(value);

    useEffect(() => {
        const handler = setTimeout(() => {
            setDelayValue(value);
        }, delay);

        return () => {
            clearTimeout(handler);
        };
    }, [value, delay]);

    return delayValue;
};


useCustomEvent

In the current project, we use many Custom Events. Such events help us to share data between components in cases when we don’t need to put it in the Redux store for example or even to share data between separate applications.


Hook is very small and simple:

export const useCustomEvent = (
    event: AppCustomEvents,
    listener: EventListenerOrEventListenerObject
): void => {
    useEffect(() => {
        window.addEventListener(event, listener);

        return () => {
            window.removeEventListener(event, listener);
        };
    }, []);
};


We use useEffect hook with empty array as a dependency to execute it on component mount. It ads eventListener to window, and in return function we remove listener to avoid memory leaks.

Than we can just call this hook when we need it:

useCustomEvent(‘user-click‘, handleUserClick)


useFetchAPI

The last hook is a general solution to work with API requests. I think that many developers use it in variations, but maybe it still will be useful for someone


A simple variant can look something like this:

export function useAPI((options): APIOptions{
    const [loading, setLoading] = useState<boolean>(true);
    const [data, setData] = useState<T>();

    const getData = (): void => {
        httpService
            .sendRequest<T>({
                url: options.url,
                data: options.data
            })
            .then((response) => {
                if (response?.data) {
                    setData(response.data);
                }
            })
            .finally(() => {
                setLoading(false);
            });
    };

    useEffect(() => {
        getData();
    }, []);

    return { loading, data };
});


We use our custom httpService to work with requests, but there can be any other solution: custom variant, fetch, Axios. So, by component mount our hook will call API, save data and set loading flag to false. Once again I want to notice that this is a very basic solution and in our app, it’s more complex. The idea is that we can create any business logic we need and then easily use it in our application