FrontEnd/React

[React] 리액트에서 제공하는 Hooks란? (feat. 커스텀 Hook 만들기)

모찌바라기 2024. 3. 30. 22:11
728x90
반응형

 

 

 

 

리액트에서 Hooks란?

Hook(이하 훅)이란 함수형 컴포넌트에서 상태(state)와 생명주기(life cycle) 기능을 사용할 수 있게 해주는

리액트에서 제공하는 기능이다.

 

훅은 함수형 컴포넌트 내에서만 사용할 수 있으며, 훅의 등장으로 리액트의 생태환경에서

함수형 컴포넌트가 클래스 컴포넌트를 대신하게 되었다.

 

 

Hooks의 탄생배경

 

이전의 리액트

 

 

지금의 리액트 개발은 대부분이 함수형(Funtion) 컴포넌트를 이용해서 개발하고 있지만

기존의 리액트(16.8v 이전)는 지금과 다르게 클래스형(Class) 컴포넌트로 개발되어 왔다.

 

그 이유로는 state와 생명주기 API를 제공하는 클래스형 컴포넌트와는 다르게

기존 함수형 컴포넌트는 단순히 UI를 랜더링해 화면에 표출해주는 용도로만 사용할 수 있었다.

 

하지만 클래스형 컴포넌트는 render 함수를 직접 호출해야 하는 등 복잡했기 때문에 

보다 간결하게 코드를 작성할 수 있는 함수형 컴포넌트를 지원하기 위해 Hooks(훅)이라는 새로운 기능이 나왔다.

 

훅이 등장하게 되면서 함수형 컴포넌트는 기존 클래스 컴포넌트의 모든 기능을 사용할 수 있게 되고

기존의 간결한 코드 또한 유지되면서 많은 개발자들이 사용하게 되었다.

 

 

Hook의 종류와 사용방법

 

훅의 종류

  1. useState: 상태(state)를 함수형 컴포넌트에서 관리할 수 있게 해주는 훅입니다.
    useState를 사용하면 컴포넌트의 상태를 선언하고 변경할 수 있습니다.

  2. useEffect: 생명주기(lifecycle) 함수의 역할을 수행하는 훅입니다. 컴포넌트가 렌더링될 때마다
    특정 작업을 수행하거나, 상태가 변경될 때마다 특정 작업을 수행하는 등의 작업을 처리할 수 있습니다.

  3. useContext: 리액트의 Context API를 사용하여 전역 상태를 관리할 때 사용되는 훅입니다.
    useContext를 사용하면 함수형 컴포넌트에서 쉽게 전역 상태를 사용할 수 있습니다.

  4. useRef: DOM 요소에 접근하거나, 이전 값에 대한 참조를 유지하거나,
    외부 라이브러리에 대한 참조를 저장하는 등의 작업에 사용되는 훅입니다.

  5. useReducer: 복잡한 상태 로직을 처리할 때 사용되는 훅으로, useState의 대안으로 활용됩니다.
    상태 업데이트 로직을 리듀서 함수로 분리하여 상태를 업데이트할 수 있습니다.

  6. useCallback: 함수를 메모이제이션하여 성능을 최적화할 때 사용되는 훅입니다.
    특정 함수를 새로 생성하지 않고도 이전에 생성한 함수를 재사용할 수 있도록 해줍니다.

  7. useMemo: 값을 메모이제이션하여 성능을 최적화할 때 사용되는 훅입니다.
    특정 값을 새로 계산하지 않고도 이전에 계산한 값을 재사용할 수 있도록 해줍니다.

  8. useLayoutEffect: useEffect와 비슷하지만, 브라우저에 업데이트를 반영하기 전에
    동기적으로 작업을 수행하는 훅입니다.

 

훅의 특징

 

1. 함수 컴포넌트 또는 커스텀 훅 내부에서만 호출 가능

2. 조건부 또는 반복문 내에서는 호출 될 수 없다.

3. 나만의 훅 (Custom Hook)을 만들어 사용할 수 있다.

 

 

어떤 경우에 커스텀 Hook을 만들어 사용할까?

 

아래와 같은 코드가 있다고 가정해보자.

 

MyHook1

import { React, useState } from "react";

export const MyHook1 = (props) => {
  const [string, setString] = useState("");
  const onChangeInput = (e) => {
    setString(e.target.value);
  };
  return (
    <>
      <div>{string}</div>
      <input onChange={onChangeInput} />
    </>
  );
};

 

 

MyHook2

import { React, useState } from "react";

export const MyHook2 = (props) => {
  const [string, setString] = useState("");
  const onChangeInput = (e) => {
    setString(e.target.value);
  };
  return (
    <>
      <div>{string}</div>
      <input onChange={onChangeInput} />
    </>
  );
};

 

 

[myHook1, myHook2] 이렇게 2개의 컴포넌트가 있는데,

가만히 보면 로직이 똑같다. ( 물론 이건 샘플이다.. 아예 똑같은 로직이면 보통 컴포넌트 1개로 만들겠지만.. )

 

중복되는 코드들이 로직이 보인다. 

<inpuit>의 value값이 변경 될 때, onChange 이벤트 핸들러가 동작하고 onChangeInput이라는 함수를 호출한다.

 

그렇게 string이라는 state값을 변경하는데... 이렇게 자주 쓰이는 로직들은

따로 훅으로 만들어 각 컴포넌트에서 사용하면 중복되는 코드들을 줄일 수 있다.

 

javascript에서 자주 쓰이는 기능들을 모듈로 빼서 사용하는 것과 비슷하다고 생각하면 된다.

 

 

커스텀 Hook 만들기

 

 

커스텀hook은 component디렉터리가 아닌 hooks라는 디렉토리를 만들어 해당 디렉토리에서

관리하는게 일반적임

 

커스텀 훅을 만드는 건 간단하다. 

 

1. Hook(훅)을 만들 때, 이름 앞에 use를 붙이면 리액트에서는 훅으로 인식한다.

2. 자주 사용되는 로직을 훅에 넣고 [값, 함수] 형태로 리턴해주면 된다.

 

아래는 샘플로 만들어 본 훅이다..

 

useChange.jsx

import { useState } from "react";

export const useChnage = () => {
  // useState로 state를 선언
  const [string, setString] = useState("");
  // 자주 사용되는 함수에서 로직 수행
  const onChangeInput = (e) => {
    setString(e.target.value);
  };
  // state값과 해당 함수를 담은 배열을 리턴
  return [string, onChangeInput];
};

 

 

SampleHook.jsx

// 생성한 Hook(훅)을 import함
import { useChnage } from "../hooks/useChange";

export const MyHook1 = (props) => {
  // 일반 Hook(훅)을 생성 하듯이 state를 생성..
  // 단 배열안의 값은 커스텀 훅이 리턴하는 배열과 동일해야함
  const [string, onChangeInput] = useChnage();
  return (
    <>
      <div>{string}</div>
      <input onChange={onChangeInput} />
    </>
  );
};

export const MyHook2 = (props) => {
  const [string, onChangeInput] = useChnage();
  return (
    <>
      <div>{string}</div>
      <input onChange={onChangeInput} />
    </>
  );
};

 

 

이렇게 커스텀훅을 사용하면 기존의 로직과 똑같이 동작하는 것을 확인할 수 있다.

 

결과

 

 

 

추가적으로 이렇게 작성된 커스텀 훅은 일반적으로 src디렉터리 안에

hooks이라는 디렉터리를 생성하고 해당 디렉터리에서 관리한다고 한다..

 

이렇게...

 

 

 

 

 

 

 

 

 

 

728x90
반응형