⚛︎ Custom hooks

zooyaho·2022년 8월 13일
0
post-thumbnail

custom hooks

  • 정규 함수, 안에 상태를 저장할 수 있는 로직을 포함한 함수
  • 커스텀 훅을 만들어서, 재사용 가능한 함수에 상태를 설정하는 로직을 아웃소싱할 수 있음.
  • 정규함수와는 다르게, 커스텀 훅은 다른 커스텀 훅을 포함한 다른 리액트 훅을 사용할 수 있음
  • useState, useReducer를 통해 관리하는 리액트 상태를 활용할 수 있음
  • useEffect등에도 접근할 수 있음.
  • 커스텀 훅을 통해, 다른 컴포넌트에서 사용할 수 있는 로직을 커스텀 훅으로 아웃소싱할 수 있으며, 이를 통해 다양한 컴포넌트에서 호출이 가능. 즉, 로직 재사용이 가능한 메커니즘인 셈이다.
  • custom hooks은 무엇이든 반환할 수 있다.(숫자, 배열, 객체, 문자열 모두 가능)

📎 사용자 정의 훅 생성

1️⃣ hooks 폴더 생성
2️⃣ use-훅이름.js로 파일 생성
3️⃣ use로 시작하는 훅 이름으로 함수(컴포넌트) 생성

  • 리액트에게 이 함수가 커스텀 훅임을 알려주며 훅의 규칙에 따라 사용하게 됨.

● 예제

  • 1초마다 반복하여 증감하는 예제

👾 BackwardCounter.js

import { useState, useEffect } from 'react';
import Card from './Card';

const BackwardCounter = () => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCounter((prevCounter) => prevCounter - 1);
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return <Card>{counter}</Card>;
};

export default BackwardCounter;

👾 ForwardCounter.js

import { useState, useEffect } from 'react';
import Card from './Card';

const ForwardCounter = () => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCounter((prevCounter) => prevCounter + 1);
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return <Card>{counter}</Card>;
};

export default ForwardCounter;

● 커스텀 훅을 사용하여 리팩토링

  • hooks폴더에 use-counter.js생성

👾 hooks/use-counter.js

const useCounter = (forwards = true) => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      // forwards가 true일 경우 증가 함수 실행
      if (forwards) {
        setCounter((prevCounter) => prevCounter + 1);
      } else {
        setCounter((prevCounter) => prevCounter - 1);
      }
    }, 1000);

    return () => clearInterval(interval);
    // forwards를 의존성으로 추가!
  }, [forwards]);
  
  // useCounter훅은 state인 counter 반환
  return counter;
}

export default useCounter;

👉🏻 로직만 구현하는 것일 뿐 상태를 공유하는 것이 아님

👾 ForwardCounter.js

import Card from './Card';
import useCounter from '../hooks/use-counter';

const ForwardCounter = () => {
  // 커스텀 훅 사용
  const counter = useCounter(true);

  return <Card>{counter}</Card>;
};

export default ForwardCounter;

👾 BackwardCounter.js

import Card from './Card';
import useCounter from '../hooks/use-counter';

const BackwardCounter = () => {
  // 커스텀 훅 사용
  const counter = useCounter(false);

  return <Card>{counter}</Card>;
};

export default BackwardCounter;

✍️ 현실적인 예시

  • API를 사용하여 data를 관리할 때, API호출이나 Data저장 등 다수 중복되는 로직들이 있다.
  • 로직의 일부분이 조금 다를 경우 별도의 Custom Hook을 생성하여 사용하면 코드 재사용 면에서 좋다.

[참고] Udemy - React 완벽 가이드 with Redux, Next.js, TypeScript

profile
즐겁게 개발하자 쥬야호👻

0개의 댓글