Hooks는 React v16.8 이후 새로 도입된 기능으로,
기존의 함수 컴포넌트에서 할 수 없었던 기능을 가능하게 해 준다.
useState
함수 컴포넌트에서 가변적인 상태를 지닐 수 있게 도와준다.
다음은 버튼을 클릭해 Count를 올리고 내리는 컴포넌트다.
import { useState } from 'react';
const Test = () => {
const [count, setCount] = useState(0); // 비구조화 할당
return (
<div>
<p>
Count value = {count}
</p>
<button onClick={() => setCount(count + 1)}> +1 </button>
<button onClick={() => setCount(count - 1)}> -1 </button>
</div>
);
};
export default Test;
useReducer
useState보다 더 다양한 컴포넌트 상황에 따라 다양한 상태를 다른 값으로 업데이트해 주고 싶을 때 사용한다.
import { useReducer } from 'react';
const reducer = (state, action) => {
switch (action.type) {
case 'Add':
return { value: state.value + 1 };
case 'Minus':
return { value: state.value - 1 };
default:
return;
}
};
const Test = () => {
const [state, dispatch] = useReducer(reducer, { value: 0 });
return (
<div>
<p>Count value = {state.value}</p>
<button onClick={() => dispatch({ type: 'Add' })}> +1 </button>
<button onClick={() => dispatch({ type: 'Minus' })}> -1 </button>
</div>
);
};
export default Test;
useEffect
React 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정할 수 있다.
import { useEffect, useState } from 'react';
const Test = () => {
const [count, setCount] = useState(0);
// useEffect 추가하여 기본값 10으로 바꿔주기!
useEffect(() => {
setCount(10);
}, []); // [] 배열 안에 변수를 추가함으로서, 언제 실행할 지 결정할 수 있음.
return (
<div>
<p>
Count value = {count}
</p>
<button onClick={() => setCount(count + 1)}> +1 </button>
<button onClick={() => setCount(count - 1)}> -1 </button>
</div>
);
};
export default Test;
useMemo
함수 컴포넌트 내부에서 발생하는 연산을 최적화할 수 있다.
useMemo를 사용하기 전과 후를 나누어 비교해 보자.
아래는 텍스트를 입력받아 '~~ 님이 입장하셨습니다'를 출력해 주는 컴포넌트이다.
import { useState } from 'react';
const Test = () => {
const [userName, setUserName] = useState('guest');
const [userList, setUserList] = useState([]);
// 텍스트 내용 변경 이벤트
const handleTextChange = (e) => {
setUserName(e.target.value);
};
// 버튼 클릭 이벤트
const handleBtnClick = (e) => {
setUserList([...userList, userName]);
};
// 문구 출력 함수
const getSayHello = (userList) => {
console.log('함수 실행');
if (userList.length <= 0) {
return '';
}
return userList.map((userInfo, idx) => (
<div key={idx}>{userInfo}님이 접속하셨습니다.</div>
));
};
return (
<div>
<input type="text" onChange={handleTextChange} />
<button onClick={handleBtnClick}>등록</button>
{getSayHello(userList)}
</div>
);
};
export default Test;
이 코드의 문제점은, 텍스트를 입력하면 onChange이벤트가 발생하여 getSayHello 함수가 반복적으로 호출된다는 것이다.
이는 state 값이 바뀜에 따라 리렌더링 되기 때문이다.
useMemo를 이용하면 값이 바뀌지 않았다면 연산했던 결과를 그대로 사용하기에, 이 문제를 해결할 수 있다.
import { useMemo, useState } from 'react';
const Test = () => {
const [userName, setUserName] = useState('guest');
const [userList, setUserList] = useState([]);
// 텍스트 내용 변경 이벤트
const handleTextChange = (e) => {
setUserName(e.target.value);
};
// 버튼 클릭 이벤트
const handleBtnClick = (e) => {
setUserList([...userList, userName]);
};
// 문구 출력 함수
const getSayHello = (userList) => {
console.log('함수 실행');
if (userList.length <= 0) {
return '';
}
return userList.map((userInfo, idx) => (
<div key={idx}>{userInfo}님이 접속하셨습니다.</div>
));
};
const memoSayHello = useMemo(() => getSayHello(userList), [userList]);
return (
<div>
<input type="text" onChange={handleTextChange} />
<button onClick={handleBtnClick}>등록</button>
{memoSayHello}
</div>
);
};
export default Test;