# 클래스 컴포넌트에서는 생성자인 컨스트럭트에서 state를 정의하고 setState를 통해 state를 업데이트 한다.
클래스 컴포넌트는 state와 관련된 기능 뿐만 아니라 컴포넌트의 생명주기 함수들까지 명확하게 정의되어 있다.
# 함수 컴포넌트는 클래스 컴포넌트와는 다르게 코드도 간결하고 별도로 state를 정의해서 사용하거나
컴포넌트의 생명주기에 맞춰 어떤 코드가 실행되도록 할 수 없다.
이런 기능을 지원하기 위해 나온 기능이 바로 Hook이다.
- Hook 이란?
# Hook을 사용하면 함수 컴포넌트도 클래스 컴포넌트의 기능을 모두 동일하게 구현 가능
# Hook은 갈고리란 뜻을 가지고 있는데 프로그래밍에서는 기존에 존재하는 어떤 기능에 갈고리를 거는 것 처럼
끼어 들어가 같이 수행되는 것을 의미한다. 비슷하게 사용되는 용어로는 webhook이 있다.
# React의 Hook은 state와 생명주기 기능 등에 갈고리를 걸어 원하는 시점에 함수를 실행되도록 만든 것!
이 때 실행되는 함수를 hook이라 부르기로 한 것이다.
# 이런 hook의 이름은 모두 use로 시작된다.
hook이 수행하는 기능에 따라 이름을 짓게 되는데 각 기능을 사용하겠단 의미로 use를 앞에 붙인다.
# 개발자가 직접 커스텀 훅을 만들어 사용도 가능하며, 커스텀 훅은 개발자 마음대로 이름을 지을 수 있지만
훅의 규칙에 따라 이름 앞에 use를 붙여 훅이라는 것을 나타내야 한다.
- 가장 대표적인 Hook
useState() # state를 사용하기 위한 hook # 함수 컴포넌트에서는 기본적으로 state라는 것을 제공하지 않아 클래스 컴포넌트처럼 state 사용 희망 시 필요
예제 코드)
# 카운터 컴포넌트는 버튼을 클릭하면 카운트를 하나씩 증가시키고 현재 카운트를 보여주는 단순한 컴포넌트 # 카운트를 함수의 변수로 선언해서 사용하면 버튼 클릭 시 값을 증가시킬수 있지만, 재 랜더링이 일어나지 않아 새로운 카운트 값이 화면에 표시되지 않는다. # 이 경우 state를 사용해서 값이 바뀔 때 마다 재 랜더링 되도록 해야하며, useState를 사용하여 state를 선언하고 업데이트 해야한다.
- useState() 사용법
# useState를 노출할 때 파라미터로 선언할 state의 초기값 필요 # 클래스 컴포넌트의 생성자에서 state를 선언할 때 초기값을 넣어주는 것과 동일 # 초기값을 넣어 useState를 노출하면 return 값으로 배열이 나온다. ※ return된 배열의 두 가지 항목 - 첫 번째 항목은 state로 선언된 변수 - 두 번째 항목은 state의 set 함수
- useState 사용 예제)
# useState를 사용하여 카운트 값을 state에 관리하도록 만든 코드 # state의 변수명과 set 함수 : count, setCount # userState는 변수 각각에 대해 set함수가 따로 존재한다.
useEffect() # side effect를 수행하기 위한 Hook # side effect : 부작용이란 뜻으로 개발자가 의도치 않은 코드가 실행되면서 버그가 발생하면 사이드 이팩트가 발생했다고 한다. # React에서 말하는 사이드 이펙트는 효과 또는 영향을 뜻하는 이펙트 의미에 가깝다. # 예시 : 서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 등의 작업을 의미 # 위와 같은 작업을 이펙트라 부르는 이유는 해당 작업들이 다른 컴포넌트에 영향을 미칠 수 없으며, 랜더링 중에는 작업이 완료될 수 없기 때문이다. 그래서 이런 작업들이 사이드로 실행된다는 의미에서 사이드 이펙트라 불린다. ※ useEffect는 리액트의 함수 컴포너트에서 사이드 이펙트를 실행할 수 있게 해주는 훅! # 유즈 이펙트는 클래스 컴포넌트에서 제공하는 생명주기 함수인 컴포넌트 디드 마운트 컴포넌트, 디드 업데이트, 컴포넌트 윌 업마운트와 동일한 기능을 하나로 통합해서 제공한다. 즉 useEffect는 생명주기 함수와 동일한 기능을 수행한다.
- userEffect() 사용법
# 의존성 배열은 해당 이펙트가 의존하고 있는 배열로 배열안에 있는 변수 중 하나라도 값이 변경되었을 때 실행 # 이펙트 함수는 처음 컴포넌트가 랜더링된 이후와 업데이트로 인한 재 랜더링 이후에 실행된다. 만약 이펙트 하수가 mount와 unmount 시 단 한번씩만 실행되게 하고 싶을 때 의존성 배열에 빈 배열 넣으면 가능▼
# 위 코드 작성 시 해당 이펙트가 props나 satate에 있는 어떤 값에도 의존하지 않는 것이 되므로 여러번 실행 안됨 # 의존성 배열은 생략도 가능하며, 생략 시 컴포넌트가 업데이트 될 때마다 호출된다.
- useEffect 사용 예제)
# useEffect를 사용해서 클래스 컴포넌트에서 제공하는 componentDidMount, componentDidUpdate와 같은 생명주기 함수의 기능을 동일하게 수행하도록 만든 코드 # useEffect()에서는 브라우저에서 제공하는 API를 사용해서 document.title 업데이트 # 위 코드처럼 의존서 배열 없이 useEffect를 사용하면 React는 DOM이 변경된 이후 해당 이펙트 함수를 실행하라는 의미 # 컴포넌트가 처음 랜더링 될 때 포함하여 매번 랜더링 시 이펙트가 실행된다. # 이펙트는 함수 컴포넌트 안에 선언되기 때문에 해당 컴포넌트의 props와 state 접근이 가능하다.
- componentWillUnmount와 동일한 기능 구현 예제)
# useEffect에서 먼저 서버 API를 사용하여 사용자의 상태를 구독하고 있다. # 이후 함수 하나를 리턴하며, 해당 함수에는 구독을 해지하는 api를 호출하도록 되어있다. # useEffect에서 리턴하는 함수는 컴포넌트가 mount 해제, 즉 unmount될 때 호출된다. ※ 결과적으로 useEffect의 리턴 함수 역할은 componentWillUnmount함수가 하는 역할과 동일!
- 두 개의 useEffectHook 사용 예제) # 하나의 컴포넌트에서 여러개 사용이 가능하다.