📁 폴더 구조
src/
├── App.jsx
├── components/
│ ├── TodoItem.jsx
│ └── TodoForm.jsx ✅
📄 components/TodoForm.jsx
function TodoForm({ text, onChange, onAdd, onKeyDown }) {
return (
<div style={{ marginBottom: '20px' }}>
<input type="text"
value={text}
onChange={onChange}
onKeyDown={onKeyDown}
placeholder="할 일을 입력하세요"
/>
<button onClick={onAdd}>추가</button>
</div>
);
}
export default TodoForm;
📄 App.jsx
리팩토링
import { useState } from 'react';
import TodoItem from './components/TodoItem';
import TodoForm from './components/TodoForm';
function App() {
const [todos, setTodos] = useState([]);
const [text, setText] = useState('');
const handleAdd = () => {
const trimmed = text.trim();
if (trimmed === '') return;
const newTodo = {
id: Date.now(),
content: trimmed,
isDone: false,
};
setTodos([newTodo, ...todos]);
setText('');
};
const handleDelete = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
const handleToggle = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, isDone: !todo.isDone } : todo
)
);
};
const handleKeyDown = (e) => {
if (e.key === 'Enter') handleAdd();
};
return (
<div style={{ padding: '30px' }}>
<h1>📘 Todo 리스트</h1>
<TodoForm text={text}
onChange={(e) => setText(e.target.value)}
onAdd={handleAdd}
onKeyDown={handleKeyDown}
/>
<ul style={{ listStyle: 'none', padding: 0 }}>
{todos.map((todo) => (
<TodoItem key={todo.id}
todo={todo}
onToggle={handleToggle}
onDelete={handleDelete}
/>
))}
</ul>
<p>총 {todos.length}개의 할 일이 있습니다.</p>
</div>
);
}
export default App;
✅ 결과 요약
TodoForm
: 입력창 + 버튼을 담당하는 컴포넌트로 분리
App
: 상태만 관리하고 UI 구조는 간결해짐
- props로
text
, onChange
, onAdd
, onKeyDown
전달
GitHub - heroyooi/react-app at ch5_3_resolve
💬 댓글
※ 로그인 후 댓글을 작성할 수 있습니다.