Hook이란?
- 리액트의 state와 생명주기 기능에 갈고리를 걸어 원하는 시점에 정해진 함수를 실행할 수 있도록 만들어진 기능
- 훅을 통해 함수 컴포넌트에서 클래스 컴포넌트의 기능을 동일하게 구현 가능
- 이름은 모두 use로 시작
useState()
- 함수 컴포넌트에서 state를 사용하기 위한 훅 (원래는 클래스 컴포넌트에서만 제공)
- 변경하고자 하는 변수 각각에 대해 set 함수를 따로 생성
*사용법: const [변수명, set함수명] = useState(초깃값)
import { useState } from "react";
export default function Counter(props) {
const [count, setCount] = useState(0);
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
<button onClick={() => setCount(count + 1)}>클릭</button>
</div>
);
}
useEffect()
- 사이드 이펙트(서버에서 데이터를 받아오거나 수동으로 DOM 변경 등)를 수행하기 위한 훅
- 클래스 컴포넌트의 생명주기 함수와 동일한 기능 수행
- 선언된 컴포넌트의 props와 state에 접근 가능
*사용법: useEffect(이펙트 함수, 의존성 배열)
- 컴포넌트가 마운트 된 이후, 의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행됨
- 의존성 배열에 빈 배열([])을 넣으면 마운트와 언마운트 사이에 1번씩만 실행됨
- 의존성 배열 생략 시 컴포넌트 업데이트 시마다 호출됨
- return 함수는 컴포넌트 마운트가 해제될 때 호출됨
import { useEffect, useState } from "react";
export default function Counter(props) {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `총 ${count}번 클릭했습니다`;
return () => {
// 컴포넌트가 마운트 해제되기 전에 실행됨
// componentWillUmount() 함수 역할과 동일
};
});
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
<button onClick={() => setCount(count + 1)}>클릭</button>
</div>
);
}
useMemo()
- Memoized value(이미 저장된 함수의 호출 결과)를 리턴하는 훅
- 연산량이 높은 작업이 매번 렌더링될 때마다 반복되는 것을 피하기 위해 사용
- 렌더링이 일어나는 동안 실행
*사용법: const memoizedValue = useMemo(값 생성 함수, 의존성 배열)
- 의존성 배열에 들어있는 변수가 변했을 경우에만 새로 값 생성 함수를 호출하여 결괏값 반환, 그렇지 않은 경우에는 기존 함수의 결괏값을 그대로 반환
useCallback()
- useMemo() 훅과 유사하지만 값이 아닌 함수를 반환
- 컴포넌트 내에 함수를 정의하면 매번 렌더링이 일어날 때마다 함수가 새로 정의됨 -> useCallback() 훅을 사용하여 불필요한 함수 재정의 작업을 없앰
*사용법: const memoizedCallback = useCallback(콜백 함수, 의존성 배열)
- 의존성 배열에 들어있는 변수가 변했을 경우에만 콜백 함수를 다시 정의하여 리턴
import { useEffect, useState, useMemo, useCallback } from "react";
export default function Counter(props) {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `총 ${count}번 클릭했습니다`;
return () => {
// 컴포넌트가 마운트 해제되기 전에 실행됨
// componentWillUmount() 함수 역할과 동일
};
});
const memoizedValue = useMemo(() => {
// 연산량이 높은 작업을 수행하여 결과를 반환
computeExpensiveValue(a, b); // 의존성 변수 1, 의존성 변수 2
}, [a, b]);
const memoizedCallback = useCallback(() => {
// 값이 아닌 함수를 반환
// 특정 변수의 값이 변한 경우에만 함수를 다시 정의
doSomething(의존성변수1, 의존성변수2);
}, [의존성변수1, 의존성변수2]);
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
<button onClick={() => setCount(count + 1)}>클릭</button>
</div>
);
}
useRef()
- 레퍼런스(특정 컴포넌트에 접근 가능한 객체)를 사용하기 위한 훅
- 매번 렌더링될 때마다 항상 같은 레퍼런스 객체를 반환
*사용법: const refContainer = useRef(초깃값)
import { useRef } from "react";
export default function TextInputWithFocusButton(props) {
// .current 속성을 가진 레퍼런스 객체 반환
// 현재 참조하고 있는 엘리먼트를 의미
// 컴포넌트가 마운트 해제되기 전까지 게속 유지됨
const inputElement = useRef(null);
const onButtonClick = () => {
// current = 마운트된 input element
inputElement.current.focus();
};
return (
<>
<input ref={inputElement} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
Hook의 규칙
- 무조건 최상위 레벨에서만 호출해야 함
- 반복문, 조건문, 중첩된 함수 안에서 호출 불가
- 컴포넌트가 렌더링될 때마다 매번 같은 순서로 호출되어야 함
- 리액트 함수 컴포넌트에서만 호출해야 함
- 리액트 함수 컴포넌트에서 호출하거나 직접 만든 커스텀 훅에서만 호출 가능
커스텀 Hook
- 내부에서 다른 훅을 호출하는 하나의 자바스크립트 함수
- 매개 변수(parameter)로 무엇을 받을지, 어떤 것을 리턴할 지 개발자가 직접 정할 수 있음
- 중복되는 로직을 커스텀 훅으로 추출하여 재사용성 증대
- 이름이 use로 시작하는 이유: 특정 함수의 내부에서 훅을 호출하는지 알 수 없기 때문에 훅의 규칙
ex) useCounter(): 초기 카운트 값을 파라미터로 받아 count라는 state를 생성하여 값을 제공하고 카운트 증가 및 감소를 편리하게 하는 커스텀 훅
import { useState } from "react";
function useCounter(initialValue) {
const [count, setCount] = useState(initialValue);
const increaseCount = () => setCount((count) => count + 1);
const decreaseCount = () => setCount((count) => Math.max(count - 1, 0));
return [count, increaseCount, decreaseCount];
}
export default useCounter;
const [count, increaseCount, decreaseCount] = setCounter(0); // 사용 예시
'Group Study (2022-2023) > React.js' 카테고리의 다른 글
[React] 4주차 스터디 - Handling Events & react-router-dom (0) | 2022.11.06 |
---|---|
[React] 3주차 스터디 - (심화) Pure Redux(2): To-do List (0) | 2022.10.30 |
[React] 2주차 스터디 - (심화) PURE REDUX: COUNTER (0) | 2022.10.09 |
[React] 2주차 스터디 - (입문) React의 핵심 개념 익히기 (컴포넌트, Props, State, Lifecycle) (0) | 2022.10.09 |
[React] 1주차 스터디 - React 프로젝트 생성하기 & JSX / Redux 시작하기 (0) | 2022.10.02 |