Function Component에서 Class Component의 기능을 지원
state를 사용하기 위한 Hook
const [변수명, set함수명] = useState(초기값);
// Count Function Component
import React, { useStae } from "react";
function Counter(props) {
var count = 0;
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
<button onClick={() => count++}>
클릭
</button>
</div>
);
}
// count값을 state로 관리
import React, { useState } from "react";
function Counter(props) {
// [변수명, set함수명]
const [count, setCount] = useState(0);
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
// 버튼 클릭시 setCount 함수 호출해서 + 1
<button onClick={() => setCount(count+1)}>
클릭
</button>
</div>
);
}
// Count값이 변경되면 Component가 재렌더링, 화면에 새로운 Count값 표시
// Class Component에서 setState함수로 호출해서 state update, 이후 Component가 재렌더링되는 과정과 동일
❕ Class Component에서는 setState함수 하나 사용해서 모든 state값을 업데이트
❕ useState 사용하는 방법은 변수 각각에 대해 set함수가 따로 존재
Function Component에서 Side effect를 수행하기 위한 Hook
Effect
의 의미와 가까움 [효과, 영향]배열안에 변수 중에 하나라도 변경될 때 실행
useEffect (이펙트 함수, 의존성 배열);
useEffect(() => {
// 컴폰너트가 마운트 된 이후,
// 의존성 배열에 있는 변수들 중 하나라도 값이 변경되었을 때 실행
// 의존성 배열에 빈 배열([])을 넣으면 마운트와 언마운트시에 단 한 번씩만 실행
// 의존성 배열 생략 시 컴포넌트 업데이트 시마다 실행
...
return () => {
// 컴포넌트가 마운트 해제되기 전에 실행
...}
}, [의존성 변수1, 의존성 변수2, ...]);
Props나 State에 있는 어떤 값에도 의존하지 않아 여러 번 실행하지 않음
useEffect(이펙트 함수, []);
useEffect(이펙트 함수);
import React, { useState, useEffect } from "react";
function Counter(props) {
const [count, setCount] = useState(0);
// componentDidMount, componentDidUpdate와 비슷하게 작동
useEffect(() => {
// 브라우저 API를 사용해서 document의 title을 업데이트
// 브라우저 페이지를 열었을 때 창에 표시되는 문자열 [크롬 탭의 제목]
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
<button onClick={() => setCount(count + 1)}>
클릭
</button>
</div>
);
}
// 의존성 배열 없이 useEffect 사용 시, React는 DOM이 변경된 후 해당 Effect 함수를 실행하라는 의미
// 기본적으로 Component가 처음 렌더링될 때 포함해서 매번 렌더링될 때마다 Effect 실행
// Effect 함수가 처음 Component가 mount됐을 때 실행, 이후 Component update될 때마다 실행
// Effect는 Function Component 안에서 선언, 해당 Component의 Props와 State에 접근 가능
// Count라는 State에 접근하여 해당 값이 포함된 문자열을 생성하여 사용
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);
// 컴포넌트가 unmount될 때 호출 [구독을 해제하는 API 호출]
return () => {
ServerAPI.unsubscribeUserStatus(props.user.id, handleStatusChange);
};
});
if (isOnline === null ) {
return '대기 중...';
}
return isOnline ? '온라인' : '오프라인';
}
// useEffect의 return 함수의 역할은 componentWillUnMount 함수의 역할과 동일
// useState Hook + useEffect Hook
// 각각 2개씩 사용
function UserStatusWithCounter(props) {
const [count, 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);
}
// ...