3 분 소요

훅이란?

컴포넌트는 두 가지 종류가 있다.

image-20240812093125021

  1. 클래스 컴포넌트
  2. 함수 컴포넌트

또한 컴포넌트에서 state를 이용해서 렌더링에 필요한 데이터를 관리한다.

Function Component Class Component
state 사용 불가 생성자에서 state를 정의
Lifecycle에 따른 기능 구현 불가 setState() 함수를 통해 state 업데이트
  Lifecycle methods 제공

기존에 함수 컴포넌트는 클래스 컴포넌트와 다르게 코드가 간결하고, 별도 state를 정의. 사용 불가능하고 생명주기에 맞춰 어떤 코드가 실행되게 할 수 없다.

➡️함수 컴포넌트에 이러한 기능이 가능하게 하는것이

(Hook)

원래 존재하는 어떤 기능에 마치 갈고리를 거는 것 처럼 끼어 들어가 같이 수행되는 것을 의미한다.

즉, 리액트의 state와 생명주기 기능에 갈고리를 걸어 원하는 시점에 정해진 함수를 실행되도록 만든 것이다.

훅의 이름은 모두 use로 시작한다.

useState

  • useState 사용법

    const [변수명, set함수명] = useState(초기값);

state를 사용하기 위한 훅이다.

간단한 예시를 보자면


  1. image-20240812102140006

image-20240812102201076

​ 불변성 때문에 클릭해도 값이 증가하지 않는다.

image-20240812102703785

console.log로 봤을 때는 count에 값이 추가되고 있다.

image-20240812104017228

image-20240812104059843

useState를 사용하여 카운트 값을 state로 관리하도록 만든 것이다.

이 코드에서 state의 변수명과 set함수가 각각count, setCount로 되어 있는 것을 볼

있다.

버튼이 눌렸을 때 setCount() 함수를 호출해서 카운트를 1 증가 시킨다. 그리고 count의 값이 변경되면 컴포넌트가 재렌더링 되면서 새로운 카운트 값이 표시된다.

클래스 컴포넌트에서 setState()함수를 호출해서 state가 업데이트 되고 이후 컴포넌트가 재렌더링 되는 과정과 동일하다.

다만 클래스 컴포넌트에서는 setState() 함수 하나를 사용해서 모든 state값을 업데이트할 수 있었지만 useState()를 사용하는 방법에서는 변수 각각에 대해 set함수가 따로 존재한다.

useEffect

useEffect()는 사이드 이펙트를 수행하기 위한 훅이다.

사이드이펙트란 부작용이라는 뜻이 있는데 리액트에서 사이드 이펙트는 효과 혹은 영향을 뜻하는 이펙트의 의미와 유사하다.

ex) 서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 등의 작업

useEffect()는 리액트의함수 컴포넌트에서 사이드 이펙트를 실행할 수 잇또록 해주는 훅이다. 클래스 컴포넌트의 componentDidMount(), componentDidUpdate(), componentWillUnmount()와 동일한 기능을 하나로 통합해서 제공한다.

➡️ useEffect() 훅 만으로도 생명주기 함수와 동일한 기능을 수행할 수 있다.

image-20240812105241275

image-20240812105311084

componentDidMount(), componentDidUpdate()와 같은 생명주기 함수의 기능을 동일하게 수행하도록 만들었다.

이펙트 함수에서는 브라우저에서 제공하는 API를 사용해서 document의 title을 업데이트 한다.

위 코드처럼 의존성 배열없이 useEffect()사용하면 리액트는 DOM이 변경된 이후에 해당 이펙트 함수를 실행하라는 의미로 받아드린다.

➡️ 매번 렌더링 될 때마다이펙트가 실행된다.

  • componentWillUnmount()

    useEffect()로 구현한다면,

    image-20240812135540774

    useEffect() 에서 먼저 ServerAPI를 사용해서 사용자의 상태를 구독하고 있다. 이후에 함수 하나 리턴하는데 해당 함수 안에는 구독을 해지하는 API를 호출하도록 되었어서 useEffect()에서 리턴하는 함수는 컴포넌트가 마운트 해제될 때 호출된다.

    ➡️ useEffect()의 리턴함수의 역할은 componontWillUnmount() 함수가 하는 역할과 같다.

useEffect()의 구조

useEffect(() => {
    //컴포넌트가 마운트 된 이후,
    //의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행됨
    //의존성 배열에 빈 배열([])을 넣으면 마운트와 언마운트시에 단 한 번씩만 실행됨
    //의존성 배열 생략 시 컴포넌트 업데이트 시마다 실행됨
    
    return() =>{
        //컴포넌트 마운트 해제되지 전에 실행됨
    }
},[의존성 변수1, 의존성 변수2,..]);

useMemo

useMemo()훅은 Memoized value를 리턴하는 훅이다. 파라미터로 Memorized Value를 생성하는 create 함수와 의존성 배열을 받는다.

이는 의존성 배열에 들어 있는 변수가 변했을 경우에만 새로 create 함수를 호출하여 결과값 반환, 그렇지 않은 경우에는 기존 함수이 결괏값을 그대로 반환한다.

useMemo()를 사용하면 연산량이 높은 작업을 반복하는것을 피할 수 있다.

const memoizedValue = useMemo (
()=> {
    //연산량이 높은 작업을 수행하여 결과를 반환
    return computeExpensiveValue(의존성 변수1, 의존성 변수2);
	},
    [의존성 변수1, 의존성 변수2]
)

useMemo()로 전달된 함수는 렌더링이 일어나는 동안 실행된다.

그래서 일반적으로 렌더링이 일어나는 동안 실행돼서는 안되는 작업을 useMemo()의 함수에 넣으면 안된다.

ex) 서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 작업 등

useCallback

useCallback() 훅은 이전에 나온 useMemo()훅과 유사한 역할을한다.

값이 아닌 함수를 반환한다는 차이점이 있다.

함수의 의존성 배열을 파라미터로 받는다. useCallback() 훅에서는 파라미터로 받는 함수를 콜백이라고 부른다.

const memorizedCallback = useCallback(
	()=>{
        doSomething(의존성 변수1, 의존성 변수2);
    },
    [의존성 변수1, 의존성 변수2]
)

의존성 배열에 따라 Memorized 값을 반환한다는 점에서는 useMemo()와 완전 동일하다.

useCallback(function,dependencies) == useMemo(()=> function, dependencies)

useRef

useRef() 훅은 레퍼런스를 사용하기 위한 훅이다.

리액트에서 리퍼런스란 특정 컴포넌트에 접근할 수 있는 객체를 의미한다.

useRef()는 레퍼런스 객체를 반환한다.

const refContainer = useRef(초기값);

훅의 규칙

  • 첫 번째

    무조건 최상위 레벨에서만 호출해야한다.

    ➡️ 반복문이나 조건문 또는 중첩된 함수들 안에서 훅을 호출하면 안된다.

    ➡️ 훅은 컴포넌트가 렌더링 될 때마다 매번 같은 순소로 호출되어야 한다.

  • 두번째

    리액트 함수 컴포넌트에서만 훅을 호출해야 한다.

    훅은 리액트 함수 컴포넌트에서 호출하거나 직접 만든 커스텀 훅에서만 호출할 수 있다.

나만의 훅 만들기

​ 여러 컴포넌트에서 반복적으로 사용되는 로직을 훅으로 만들어 재사용하기 위함이다.

커스텀 훅을 만들어야 하는 상황

커스텀 훅 추출하기

이름이 use로 시작하고 내부에서 다른 훅을 호출하는 하나의 자바스크립트 함수이다.

실습

image-20240812095135590

image-20240812095237982


  1. image-20240812102140006

image-20240812102201076

​ 불변성 때문에 클릭해도 값이 증가하지 않는다.

image-20240812102703785

console.log로 봤을 때는 count에 값이 추가되고 있다.

업데이트:

댓글남기기