State
React에서의 State
컴포넌트의 상태
컴포넌트가 가지고 있는 데이터나 조건을 나타냄
예:
Todo List에서의 할 일 목록 == 컴포넌트의 상태
→ 사용자가 할 일을 추가하거나 삭제하면 상태가 변경, 이에 따라 UI가 업데이트됨
useState
Hook을 사용한 상태 관리
상태 값을 정의하고, 이를 업데이트하는 함수도 함께 제공해야 함 (상태 정의, 변경)
const [state, setState] = useState(initialValue);
state
: 현재 상태 값setState
: 상태를 변경하는 함수initialValue
: 초기 상태 값
상태 값을 변경하면 React가 자동으로 해당 컴포넌트를 다시 렌더링 하여 UI를 업데이트함
State 업데이트 방법
새로운 값을 바로 설정
setState(newValue);
이전 값을 기반으로 업데이트
setState(prev => newValue);
React에서의 불변성 유지 (Immutability)
React에서는 상태를 직접 수정하지 않고, 항상 새로운 객체를 생성하여 변경 사항을 감지
→ State를 업데이트할 때, 불변성을 유지하는 것이 중요
- 디버깅 용이: 상태 변경 내역을 추적하기 쉬움
- 최적화 가능: 이전 상태와 비교하여 변경된 부분만 렌더링 가능
- 새로운 기능 지원: React의 최신 기능과 호환성 유지 가능
- 예측 가능성 증가: 상태 변경을 예측하기 쉬움
불변성을 유지하는 방법
배열을 직접 수정하지 않고 새로운 배열을 생성
setTodos([...todos, newTodo]);
map
또는 filter
메서드를 활용
setTodos(todos.map(todo => todo.id === id ? { ...todo, isCompleted: !todo.isCompleted } : todo));
객체 State 업데이트하기 – React
The library for web and native user interfaces
ko.react.dev
State 적용 예제 (TodoList)
App.css (스타일 정의)
.app-container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f4f4f4;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.todo-input {
width: 70%;
padding: 10px;
border: 2px solid #ddd;
border-radius: 4px;
margin-right: 10px;
}
.add-btn {
padding: 10px 20px;
background-color: #5cb85c;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.add-btn:hover {
background-color: #4cae4c;
}
초기 UI 구성
import "./App.css";
import TodoList from "./TodoList";
function App() {
return (
<div className="app-container">
<TodoList />
</div>
);
}
export default App;
Todo List 컴포넌트
import React, { useState } from "react";
function TodoItem({ todo, toggleComplete, deleteTodo }) {
return (
<div className="todo-item">
<input
className="checkbox"
type="checkbox"
checked={todo.isCompleted}
onChange={() => toggleComplete(todo.id)}
/>
<p
className="todo-text"
style={{ textDecoration: todo.isCompleted ? "line-through" : "none" }}
>
{todo.text}
</p>
<button onClick={() => deleteTodo(todo.id)} className="delete-btn">
Delete
</button>
</div>
);
}
function TodoList() {
const [todos, setTodos] = useState([
{ id: 1, text: "리액트 공부하기", isCompleted: false },
{ id: 2, text: "운동하기", isCompleted: false },
]);
const addTodo = (text) => {
const newTodo = { id: crypto.randomUUID(), text, isCompleted: false };
setTodos([...todos, newTodo]);
};
const deleteTodo = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
const toggleComplete = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, isCompleted: !todo.isCompleted } : todo
)
);
};
return (
<div>
<input
className="todo-input"
type="text"
onKeyDown={(e) => {
if (e.key === "Enter") addTodo(e.target.value);
}}
/>
<button className="add-btn" onClick={() => addTodo("새로운 할 일")}>할 일 추가</button>
{todos.map((todo) => (
<TodoItem
key={todo.id}
todo={todo}
toggleComplete={toggleComplete}
deleteTodo={deleteTodo}
/>
))}
</div>
);
}
export default TodoList;
'React > ReactThreeFiber' 카테고리의 다른 글
Component (0) | 2025.03.12 |
---|---|
Event Handling (0) | 2025.03.12 |
JSX (1) | 2025.03.11 |
CRA(Create React App) (0) | 2025.03.11 |
React (1) | 2025.03.11 |