React Custom Hook 만들어보기

Thomas·2022년 3월 13일
0

리액트에서 Custom Hook을 다루는건 코드의 가독성을 향상시키며 코드의 재사용성과 유지보수에 있어서 아주 효과적이라고 할 수 있다.

React Hook 이란?

먼저 React Hook이 무엇인지 살펴보자.
React Hook은 16.8 버전에 새로 출시된 React의 요소로써 함수형 컴포넌트에서 state를 다룰수 있게 하며 사이드 이펙트가 가능하게 해준다.
Hook 출시 이전에는 함수형 컴포넌트에서는 state를 다룰수 없으며 컴포넌트의 생명주기를 다룰수 없었다. 그렇기 때문에 장황한 클래스형 컴포넌트를 사용하였다.

16.8 버전에서 훅이 출시된 이후로 useState, useEffect 함수를 활용해 클래스형 컴포넌트에서만 할 수 있던 일들을 함수형 컴포넌트에서 다룰수 있게 되었다.
함수형 컴포넌트는 클래스형 컴포넌트에 비해서 코드가 간편하며 가독성이 뛰어나다는 장점이 있었고, 곧 함수형 컴포넌트가 대세가 되었다.

useState와 useEffect 훅은 이전 포스팅에서 확인할 수 있다.

Hook의 규칙

Hook을 사용하려면 규칙을 준수해야한다.

  • Hook은 반드시 최상위 레벨에서 호출되어야 한다.
    - 여기서 최상위 Level 이란 반복문, 조건문, 중첩된 함수 같은 level을 말한다.
  • 오직 React 함수에서만 hook을 호출해야 한다.
    - 함수형 컴포넌트에서 Hook을 호출하자.
    - Custom Hook에서 Hook을 호출하자

Custom hook 이란?

커스텀 훅은 말 그대로 사용자가 만드는 훅이다. Custom Hook을 만든다는건 중복된 로직을 빼내어 함수화 시킨다는 것이다.
간단한 예제를 통해서 살펴보자

기존의 코드

function App() {
  const [keyword,setKeyword] = useState(() => {
    return window.localStorage.getItem(keyword) || "";
  });
  const [result, setResult] = useState("");
  const [typing, setTyping] = useState(false);

  React.useEffect(() => {
    window.localStorage.setItem("keyword",keyword);
  },[keyword]);
  
  React.useEffect(() => {
    window.localStorage.setItem("result",result);
  },[result]);
  
  React.useEffect(() => {
    window.localStorage.setItem("typing",typing);
  },[typing]);
  
  const handleChange = (event) => {
    setKeyword(event.target.value);
    setResult("");
    setTyping(true);
  }
  
  const handleClick = () => {
    setResult(`you find this? ${keyword}`);
    setTyping(false);
    setKeyword("");
  }
  return (
    <>
      <input value={keyword} onChange={handleChange}/>
      <button onClick={handleClick}>Search</button>
      {result !== "" ? <p>{result}</p> : <p>{`you are looking for ${keyword}...`}</p>}
    </>
  );
}

위 코드를 살펴보면 3개의 state를 활용했고 이의 상태 변화를 localStorage에 저장하기 위해 useEffect를 3번 호출한 것을 확인할 수 있다.

공통된 useState와 useEffect, 이 공통된 로직들을 빼내어서 Custom hook을 만들어보자.

Custom Hook

import React, { useState } from "react";

export function useLocalStorage(itemName, value = "") {
  const [state, setState] = useState(() => {
    return window.localStorage.getItem(itemName) || value;
  });

  React.useEffect(() => {
    window.localStorage.setItem(itemName, value);
  }, [state]);

  return [state, setState];
}

코드를 살펴보면 custom hook의 제목은 use로 시작된다. 이는 React Hook의 명명 규칙이다.
내부에서는 state를 생성하였고, 초기값으로 localStorage에서 값을 받아와 할당해주고 없다면 value 를 할당해주고 있다.

useEffect를 통해서 itemName의 값이 변화할 때 마다 sideEffect를 해주고 있다.
또한 state를 리턴해줌으로써 함수형 컴포넌트에서 state를 활용할 수 있게 해준다.

컴포넌트

import { useLocalStorage } from "./useLocalStorage";

export default function App() {
  const [keyword, setKeyword] = useLocalStorage("keyword");
  const [typing, setTyping] = useLocalStorage("typing", false);
  const [result, setResult] = useLocalStorage("result");

  const handleChange = (event) => {
    setKeyword(event.target.value);
    setResult("");
    setTyping(true);
  };

  const handleClick = () => {
    setResult(`you find this? ${keyword}`);
    setTyping(false);
    setKeyword("");
  };
  return (
    <>
      <input value={keyword} onChange={handleChange} />
      <button onClick={handleClick}>Search</button>
      {result !== "" ? (
        <p>{result}</p>
      ) : (
        <p>{`you are looking for ${keyword}...`}</p>
      )}
    </>
  );
}

Custom Hook을 적용한 모습이다.
같은 로직이지만 컴포넌트가 훨씬 가독성이 좋아졌다는 것을 확인할 수 있다.
또한 Custom Hook을 활용함으로써 코드의 재사용성도 높아진 모습이다.

참고 : https://ko.reactjs.org/docs/hooks-intro.html

profile
안녕하세요! 주니어 웹 개발자입니다 😆

0개의 댓글