Hook
- Hook : 영단어로는 갈고리라는 뜻으로 프로그래밍에서는 원래 존재하는 어떤 기능에
마치 갈고리를 거는 것 처럼 끼어 들어가 같이 수행되는 것을 의미한다. - 리액트에서의 Hook : 리액트의 state와 생명주기 기능에 갈고리를 걸어 원하는 시점에
정해진 함수를 실행되도록 만든 것이다.
useState
- 가장 대표적으로 많이 사용되는 훅이다.
- 함수 컴포넌트에서는 state를 제공하지 않기 때문에 클래스 컴포넌트처럼 state를
사용하고 싶으면 useState() 훅을 사용해야 한다.
Ex)
import React { useState} from "react";
function Counter(props) {
var count = 0;
return (
<div>
<p> 총 {count}번 클릭했습니다.</p>
<button onClick={() => count++}>
클릭
</button>
</div>
);
}
Counter 컴포넌트는 버튼을 클릭하면 카은트를 하나씩 증가 시키고
현재 카운트를 보여주는 단순 컴포넌트이다.
카운트를 함수의 변수로 선언하여 사용하게 되면 버튼 클릭 시 카운트 값을 증가시킬수 있지만,
재랜더링이 일어나지 않아새로운 카운트 값이 화면에 표시되지 않게 된다.
따라서 이런 경우 state를 사용하여 값이 바뀔 때마다 재랜더링이 되도록 해야한다.
함수 컴포넌트에는 해당 기능이 따로 없기 때문에 useState()를 사용하여 state를 선언하고
업데이트 해야한다.
useState는 다음과 같이 사용된다.
const [변수명, set함수명] = useState(초깃값);
useState()를 호출할 때에 는 파라미터로 선언할 state의 초기값이 들어간다.
클래스 컴포넌트의 생성자에서 state를 선언할 때 초깃값을 넣어 주는 것과 동일한 것.
이렇게 초깃값을 넣어 useState()를 호출하면 리턴 값으로 배열이 나온다. 리턴된 배열에는
state로 선언된 변수와 해당 state의 set함수가 들어 있다.
전 예제를 useState()를 사용하여 바꾼 코드이다.
import React, {useState} from "react";
function Counter(props) {
const [count, setCount] = useState(0);
return(
<div>
<p> 총 {count}번 클릭했습니다.</p>
<button onClick={() => setCount(count + 1)>
클릭
</button>
</div>
);
}
코드에서 state의 변수명과 함께 coun, setCount로 되어있고, 버튼이 눌렸을 경우 setCount()
함수를 호출하여 카운트를 1 증가 시킨다. 그리고 count의 값이 변경되면 컴포넌트가
재랜더링되면서 화면에 새로운 카운트 값이 표시된다.
useState()를 변수 각각에 대하여 set함수가 따로 존재한다는것을 기억해야한다.
useEffect
- useState와 더불어 가장 많이 사용되는 훅이다.
- 컴포넌트가 렌더링 될 때마다 특정 작업(Sied effect)을 실행할 수 있도록 하는 훅이다.
- 생명 주기 함수인 compentDidMount (), componentDidUpdate(),
componentWillUnmount()와 동일한 기능을 하나로 통합하여 제공한다.
useEffect는 다음과 같이 사용된다.
useEffect(이펙트 함수, 의존성 배열);
의존성 배열이란 이 이펙트가 의존하고 있는 배열인데 배열 안에 있는 변수 중에 하나라도
값이 변경되었을 때 이펙트 함수가 실행된다.
다음은 useEffect()를 사용한 예제이다.
import React, { useState, useEffect } from "react";
function Counter(props) {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 비슷하게 작동
useEffect (() => {
// 브라우저 API를 사용하여 document와 title을 업데이트
document.title = `총 ${count}번 클릭했습니다.`;
});
return(
<div>
<p>총 {count}번 클릭했습니다.</p>
<button onClick={() => setCount(count +1)}>
클릭
</button>
</div>
);
}
위 코드처럼 의존성 배열 없이 useEffect()를 사용하면 리액트는 DOM이 변경된 이후에
해당 이펙트 함수를 실행하라는 의미로 받아들인다. 처음 컴포넌트가 마운트 되었을 때 실행되고
이후 컴포넌트가 업데이트 될 때마다 실행되는 것이다. 결론적으로 componentDidMount(),
componentDidUpdate()와 동일한 역할을 한다.
import React, {useState, useEffect } from "react";
function UserStatus(props) {
const [isOnline, setIsOnline] = useState(null);
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
useEffect(() => {
ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
return () => {
ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
};
});
if(isOnline === null) {
return '대기중 ...';
}
return isOnline ? '온라인' : '오프라인';
}
useEffect () 에서 먼저 ServerAPIU를 사용하여 사용자의 상태를 구독하고 있다. 이후 함수를
하나 리턴하는데 해당 함수 안에 구독 해지하는 API를 호출하도록 되어 있다.
useEffect ()에서 함수는 컴포넌트가 마운트 해체될 때 호출된다. 결과적으로 useEffect ()의
리턴 함수의 역할은 componentWillUnmount() 함수가 하는 역할과 동일하다.
아래의 코드는 두개의 useEffect() 훅을 사용하는 코드이다.
function UserStatusWithCounter(props) {
const [const, setCount] = useState(0);
useEffect (() => {
document.title = `총 ${count}번 클릭했습니다.`;
});
const [isOnline, setIsOnline] = useState(null);
useEffect (() => {
ServerAPI.subscribeUserStatus(props.user.id, handleStatusChange);
return () => {
ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
};
});
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
// ...
정리(useEffect 사용법)
useEffect (() => {
<!-- 컴포넌트가 마운트 된 이후,
의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행됨
의존성 배열에 빈 배열([])을 넣으면 마운트와 언마운트시에 단 한 번씩만 실행됨
의존성 배열 생략 시 컴포넌트 업데이트 시마다 실행됨
-->
return () => {
// 컴포넌트가 마운트 해제되기 전에 실행됨
// ...
}
}, [의존성 변수1, 의존성 변수2, ...]);
'Front-End > React' 카테고리의 다른 글
[React] 생명 주기 (0) | 2022.09.03 |
---|---|
[React] State (0) | 2022.08.29 |
[React] 컴포넌트와 Props (0) | 2022.08.19 |
[React] Element (0) | 2022.08.16 |
[React] JSX (0) | 2022.08.13 |