React - Custom Hook

김영준·2023년 8월 27일
0

TIL

목록 보기
88/91
post-thumbnail

Custom Hook

자주 사용되는 상태 로직을 별도의 사용자 정의 훅으로 만들어서 사용하면 중복 코드를 제거할 수 있고, 편하게 사용이 가능하다.

기존 훅을 조합해서 사용이 가능하다.

예제

// src/App.js

import Box from "./components/Box";
import Checkbox from "./components/Checkbox";
import useHover from "./hooks/useHover";
import useKeyPress from "./hooks/useKeyPress";
import useToggle from "./hooks/useToggle";

function App() {
  const [on, toggle] = useToggle();
  const [ref, isHover] = useHover();
  const keyPressed = useKeyPress("a");

  return (
    <div>
      <Checkbox checked={on} onChange={toggle} />

      {isHover ? "hover" : "mouseout"}
      <Box ref={ref} />

      {keyPressed && "pressed"}
    </div>
  );
}

export default App;

체크박스의 체크 여부를 감지하는 훅

// src/components/Checkbox.js

const Checkbox = ({ label = "Label", checked = false, onChange }) => {
  return (
    <label>
      {label}
      <input type="checkbox" defaultChecked={checked} onChange={onChange} />
    </label>
  );
};

export default Checkbox;
// src/hooks/useToggle.js

import { useCallback, useState } from "react";

const useToggle = (initialState = false) => {
  const [state, setState] = useState(initialState);
  const toggle = useCallback(() => setState((state) => !state), []);

  return [state, toggle];
};

export default useToggle;

마우스 over를 감지하는 훅

// src/components/Box.js

import styled from "@emotion/styled";

const Box = styled.div`
  width: 100px;
  height: 100px;
  background-color: blue;
`;

export default Box;
// src/hooks/useHover.js

import { useCallback, useEffect, useRef, useState } from "react";

const useHover = () => {
  const [state, setState] = useState(false);
  const ref = useRef(null);

  const handleMouseOver = useCallback(() => setState(true), []);
  const handleMouseOut = useCallback(() => setState(false), []);

  useEffect(() => {
    const element = ref.current;
    if (element) {
      element.addEventListener("mouseover", handleMouseOver);
      element.addEventListener("mouseout", handleMouseOut);

      return () => {
        element.removeEventListener("mouseover", handleMouseOver);
        element.removeEventListener("mouseout", handleMouseOut);
      };
    }
  }, [ref, handleMouseOver, handleMouseOut]);

  return [ref, state];
};

export default useHover;

특정 키보드 입력을 감지하는 훅

// src/hooks/useKeyPress.js

import { useCallback, useEffect, useState } from "react";

const useKeyPress = (targetKey) => {
  const [keyPressed, setKeyPressed] = useState(false);

  const handleKeyDown = useCallback(
    ({ key }) => {
      if (key === targetKey) {
        setKeyPressed(true);
      }
    },
    [targetKey]
  );

  const handleKeyUp = useCallback(
    ({ key }) => {
      if (key === targetKey) {
        setKeyPressed(false);
      }
    },
    [targetKey]
  );

  useEffect(() => {
    window.addEventListener("keydown", handleKeyDown);
    window.addEventListener("keyup", handleKeyUp);
    return () => {
      window.removeEventListener("keydown", handleKeyDown);
      window.removeEventListener("keyup", handleKeyUp);
    };
  }, [handleKeyDown, handleKeyUp]);

  return keyPressed;
};

export default useKeyPress;
profile
꾸준히 성장하는 개발자 블로그

0개의 댓글