[React] Useful custom hooks

suyeonme·2020년 9월 22일
0

React

목록 보기
3/26

유용한 hook이 있을 때마다 하나씩 추가할 예정

useClickOutside

import { useEffect } from 'react';

const useOutsideClick = (ref, callback) => {
  const handleClick = e => {
    if (ref.current && !ref.current.contains(e.target)) {
      callback();
    }
  };

  useEffect(() => {
    document.addEventListener('click', handleClick);

    return () => {
      document.removeEventListener('click', handleClick);
    };
  });
};

export default useOutsideClick;

useAudio

import React, { useState, useEffect } from 'react';
import PlayBtn from '../components/button/playBtn';

const useAudio = url => {
  const [audio] = useState(new Audio(url));
  const [playing, setPlaying] = useState(false);

  const toggle = () => setPlaying(!playing);

  useEffect(() => {
    playing ? audio.play() : audio.pause();
  }, [playing, audio]);

  useEffect(() => {
    audio.addEventListener('ended', () => setPlaying(false));
    return () => {
      audio.removeEventListener('ended', () => setPlaying(false));
    };
  }, [audio]);

  return [playing, toggle];
};

const Player = ({ url, setStart }) => {
  const [playing, toggle] = useAudio(url);

  const handleClick = () => {
    toggle();
  };

  return <PlayBtn onClick={handleClick} playing={playing} />;
};

export default Player;

useIntersectionObserver

import { useState, useEffect } from "react"

export const useIntersectionObserver = (
  ref,
  { threshold, root, rootMargin }
) => {
  // configure the state
  const [state, setState] = useState({
    inView: false,
    triggered: false,
    entry: undefined,
  })

  const observer = new IntersectionObserver(
    (entries, observerInstance) => {
      // checks to see if the element is intersecting
      if (entries[0].intersectionRatio > 0) {
        // if it is update the state, we set triggered as to not re-observe the element
        setState({
          inView: true,
          triggered: true,
          entry: observerInstance,
        })
        // unobserve the element
        observerInstance.unobserve(ref.current)
      }
      return
    },
    {
      threshold: threshold || 0,
      root: root || null,
      rootMargin: rootMargin || "0%",
    }
  )

  useEffect(() => {
    // check that the element exists, and has not already been triggered
    if (ref.current && !state.triggered) {
      observer.observe(ref.current)
    }
  })

  return [state.inView, state.entry]
}

useFirstRender

Check whether it is first render or not

import { useRef, useEffect } from 'react';

const useFirstRender = () => {
  const firstRender = useRef(true);

  useEffect(() => {
    firstRender.current = false;
  }, []);

  return firstRender.current;
};

export default useFirstRender;
profile
Frontend Engineer.

0개의 댓글