02 August 2020ย ย โ€ขย ย 1 min read

#2 hook of the week

To remind you of the purpose and goal of this week:

For a whole week I'll post a new hook every day. All hooks will support Server-Side Rendering (SSR) and have TypeScript implemented.

I will not describe the hooks in great detail, I'll just present them and show how it's implemented. Then you can do whatever you want with them.

Every hook is also available here, together with a range of other hooks.

View source

The hook ๐ŸŽฃ

With this hook you can easily add event listeners and it will remove itself to avoid memory leaks. Element supports refs, document and window.

I'm using my isSSR and getRefElement() utility.

import { useRef, useEffect, useCallback, RefObject } from 'react';
import { isSSR, getRefElement } from './utils';

interface UseEventListener {
  type: keyof WindowEventMap;
  listener: EventListener;
  element?: RefObject<Element> | Document | Window | null;
  options?: AddEventListenerOptions;

export const useEventListener = ({
  element = isSSR ? undefined : window,
}: UseEventListener): void => {
  const savedListener = useRef<EventListener>();

  useEffect(() => {
    savedListener.current = listener;
  }, [listener]);

  const handleEventListener = useCallback((event: Event) => {
  }, []);

  useEffect(() => {
    const target = getRefElement(element);
    target?.addEventListener(type, handleEventListener, options);
    return () => target?.removeEventListener(type, handleEventListener);
  }, [type, element, options, handleEventListener]);


Just a simple showcase that console.log() the event when a user clicks on the element. If we wouldn't pass an element it would fallback to the window.

import React from 'react';
import { useEventListener } from './hooks';

const Component = () => {
  const ref = useRef(null);

    element: ref,
    type: 'click',
    listener: (event) => console.log(event),
    options: { passive: true }

  return <div ref={ref} />;

export default Component;

The end ๐Ÿ‘‚

I hope you found this helpful.