React를 학습하다보면 '상태(State)'라는 단어를 정~~말 많이 듣게 되는데요. 상태는 컴포넌트가 렌더링될 때 변할 수 있는 값으로, 사용자 인터랙션에 따라 동적으로 변경될 수 있습니다.
useState는 React 16.8버전에서 도입된 훅(Hook) 중 하나로 상태를 관리 해주는 훅입니다. 훅이 도입되기 전에는 주로 setState 메서드를 사용하여 클래스 구성 요소에서 상태 관리되었다고도 하네요.
요번 글에서는 useState를 소개하고 각 섹션에서 예제를 통해 사용법을 알아보겠습니다.
useState를 사용하여 상태를 선언하려면, 상태의 초기값을 파라미터로 넘겨주고, 이 함수는 상태 변수와 해당 변수를 갱신하는 함수를 반환합니다. 아래는 간단한 카운터 예제입니다.
import React, { useState } from 'react';
function Counter() {
// useState를 사용하여 초기 상태 0을 설정합니다.
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
{/* 버튼 클릭 시 setCount를 통해 상태를 갱신합니다. */}
<button onClick={() => setCount(count + 1)}>
Increase Count
</button>
</div>
);
}
- useState(0)은 초기 상태 값을 0으로 설정
- const [count, setCount] = useState(0);에서 count는 현재 상태를 나타내며, setCount는 상태를 갱신하는 함수
- 버튼 클릭 시 setCount(count + 1)을 통해 상태가 1씩 증가
함수형 업데이트를 사용하면 이전 상태 값을 쉽게 활용할 수 있습니다. 아래는 카운터에서 이전 상태 값을 활용하는 예제입니다.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
{/* 함수형 업데이트를 사용하여 이전 상태 값을 활용합니다. */}
<button onClick={() => setCount(prevCount => prevCount + 1)}>
Increase Count
</button>
</div>
);
}
- setCount(prevCount => prevCount + 1)에서 prevCount는 이전 상태 값
- 이전 상태 값을 활용함으로써 상태 갱신 중 발생할 수 있는 문제를 방지
여러 개의 상태 변수를 다루는 것도 간단합니다. 아래는 이름과 나이를 갖는 상태 변수의 예제입니다.
import React, { useState } from 'react';
function UserInfo() {
const [name, setName] = useState('');
const [age, setAge] = useState(0);
return (
<div>
<p>Name: {name}</p>
<p>Age: {age}</p>
{/* 각각의 상태 변수를 갱신하는 버튼을 추가합니다. */}
<button onClick={() => setName('John')}>Set Name</button>
<button onClick={() => setAge(prevAge => prevAge + 1)}>Increase Age</button>
</div>
);
}
- const [name, setName] = useState('');와 const [age, setAge] = useState(0);는 각각 이름과 나이의 상태 변수를 선언
- 버튼 클릭 시 setName('John')과 setAge(prevAge => prevAge + 1)을 통해 각각의 상태가 갱신
useState를 사용할 때 성능 최적화에도 신경써야 합니다. React.memo와 useMemo를 사용하여 불필요한 렌더링을 방지할 수 있습니다.
import React, { useState, useMemo } from 'react';
function MemoizedComponent({ data }) {
// useMemo를 사용하여 계산 비용이 높은 결과를 캐싱합니다.
const memoizedData = useMemo(() => calculateExpensiveData(data), [data]);
return <p>{memoizedData}</p>;
}
- useMemo를 사용하여 calculateExpensiveData(data) 함수의 결과를 캐싱
- data가 변경될 때만 calculateExpensiveData가 호출되어 성능을 최적화