1) 상태 변경 감지와 리렌더링 최적화를 위해서이다.
React에서는 상태의 변경을 감지하고 컴포넌트를 다시 렌더링하는데 필요한 최소한의 업데이트만 수행하여 효율성을 높이려고 한다. 변수를 그대로 사용하면 React는 상태 변경을 추적할 수 없어 모든 렌더링에서 전체 컴포넌트를 다시 그린다. 그러나 useState를 사용하면 React는 상태 변경을 자동으로 감지하고, 변경된 부분만 업데이트하여 불필요한 리렌더링을 방지한다.
예를 들어, 다음과 같은 컴포넌트가 있다고 가정해보자.
function Counter() {
let count = 0;
const handleClick = () => {
count += 1;
// count 변수를 직접 수정
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
);
}
위 코드에서 count 변수를 직접 수정하면 React는 상태 변경을 추적할 수 없어 모든 리렌더링이 발생한다. 그러므로 count를 상태로 관리하기 위해 useState를 사용해야 한다.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
// setCount를 통해 상태 변경
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>Increment</button>
</div>
);
}
위 코드에서 useState를 사용하여 count 상태를 관리하면, setCount 함수를 통해 count를 업데이트한다. React는 setCount 호출을 통해 변경된 부분만 업데이트하고 필요한 경우에만 리렌더링한다.
2) 불변성 유지를 위해서이다.
React에서는 상태의 불변성을 유지해야 한다. 변수를 직접 수정하면 상태의 불변성을 깨뜨릴 수 있다. 그러나 useState를 사용하면 React가 내부적으로 상태 변경을 처리하고 이전 상태와 새로운 상태를 정확히 비교하여 최적화된 업데이트를 수행한다. 이를 통해 상태의 불변성을 유지하면서도 상태를 효율적으로 업데이트할 수 있다.
예를 들어, 다음과 같은 컴포넌트가 있다고 가정해보자.
function Person() {
let name = 'Alice';
const handleChangeName = () => {
name = 'Bob';
// name 변수를 직접 수정
};
return (
<div>
<p>Name: {name}</p>
<button onClick={handleChangeName}>Change Name</button>
</div>
);
}
위 코드에서 name 변수를 직접 수정하면 React는 상태 변경을 감지하지 못하고, 전체 컴포넌트를 다시 렌더링한다.
import React, { useState } from 'react';
function Person() {
const [name, setName] = useState('Alice');
const handleChangeName = () => {
setName('Bob');
// setName을 통해 상태 변경
};
return (
<div>
<p>Name: {name}</p>
<button onClick={handleChangeName}>Change Name</button>
</div>
);
}
위 코드에서 useState를 사용하여 name 상태를 관리하면, setName 함수를 통해 name을 업데이트한다. React는 setName 호출을 통해 변경된 부분만 업데이트하고 필요한 경우에만 리렌더링한다.