[React] useState 사용해보기
멘토님께서 React에서 제공하는 useHook 중 몇 개를 써보았는지 물어보시며
한번씩 다 써보는걸 추천하셨다.
그래서 하나씩 직접 써보고 정리해보기로 했다.🙂
React에서 가장 자주 사용되는 Hook인 useState는 컴포넌트의 상태를 관리할 때 사용된다.
상태 관리에도 여러 종류가 있지만 나는 숫자, 객체, 배열의 상태를 다뤄보았다.
useState란?
useSate는 React에서 컴포넌트의 상태(state)를 저장하고 갱신할 수 있는 Hook이다.
const [state, setState] = useState(초기값);
여기서 state는 현재 상태 값, setState는 상태를 업데이트하는 함수이다.
실습해보기
숫자 상태 관리
const Counter = () => {
const [count, setCount] = useState<number>(0);
const increase = () => setCount((prev) => prev + 1);
const decrease = () => setCount((prev) => prev - 1);
return (
<section>
<h2>Counter</h2>
<p>{count}</p>
<div>
<button onClick={decrease}>- 감소</button>
<button onClick={increase}>+ 증가</button>
</div>
</section>
);
};
이전 값에 의존 하는 경우 prev => prev + 1 형태로 함수형 업데이트를 사용하는 것이 안전하다.
객체 상태 관리
const UserInfo = () => {
const [user, setUser] = useState({ name: "민이", age: 30 });
const changeName = () => {
setUser({ ...user, name: "치즈" });
};
const increase = () => {
setUser((prev) => ({ ...prev, age: prev.age + 1 }));
};
const decrease = () => {
setUser((prev) => ({ ...prev, age: prev.age - 1 }));
};
return (
<section>
<h2>UserInfo</h2>
<h3>이름: {user.name}</h3>
<h3>나이: {user.age}</h3>
<div>
<button onClick={changeName}>이름 변경</button>
<button onClick={decrease}>- 감소</button>
<button onClick={increase}>+ 증가</button>
</div>
</section>
);
};
객체상태는 추가, 수정의 경우 반드시 spread연산자(...)를 이용해 기존 상태를 복사하고 일부만 바꿔야한다.
직접 수정할 경우 리렌더링이 되지않기 때문에 조심!(상태의 참조가 바뀌어야 리렌더링이 됨)
배열 상태 관리
const TodoList = () => {
const [todos, setTodos] = useState<string[]>([
"알고리즘 풀기",
"치즈 산책 가기",
"개념 공부",
]);
const addTodo = () => {
setTodos((prev) => [...prev, `새로운 할일 ${prev.length + 1}`]);
};
const removeFirst = () => {
setTodos((prev) => prev.slice(1)); // 제일 첫 항목 제거
};
return (
<section>
<h2>할 일 목록</h2>
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo}</li>
))}
</ul>
<div>
<button onClick={addTodo}>할 일 추가</button>
<button onClick={removeFirst}>첫 항목 제거</button>
</div>
</section>
);
};
배열도 마찬가지로 원본을 직접 수정하지 않고
spread 연산자를 사용하거나 filter, slice를 활용해 새로운 배열을 만들어야한다.
주의사항
React는 상태 변경을 감지할 때 객체나 배열의 참조를 비교하기 때문에, 반드시 새로운 객체나 배열을 만들어 전달해야한다!
// 잘못된 방식
count++;
todos.push("new task");
user.name = "치즈";
// 올바른 방식
setCount(prev => prev + 1);
setTodos([...todos, "new task"]);
setUser({ ...user, name: "치즈" });
정리하며
예제를 통해 useState를 직접 사용해보니
불변성을 유지하는 것이 핵심이라는 걸 다시 한 번 느꼈다.
또한 상태 업데이트 시 prev => ... 형태의 함수형 업데이트를 활용하면
예상치 못한 렌더링 문제나 비동기성 이슈를 줄일 수 있다는 것도 알게 되었다.
참고 페이지
https://react.dev/reference/react/useState
useState – React
The library for web and native user interfaces
react.dev