juni
SingleProject_React 학습(TodoList) 본문
// 리액트로 개발한 앱은 컴포넌트라는 조각을 구성됨
// -> UI구축을 훨씬 쉽게 만들어줌
// 컴포넌트를 생성하고 UI 요소를 컴포넌트 내부에서 JSX통해 선언
// -> 리액트가 반응 -> 리액트 컴포넌트가 '선언체'라는 개념이 아주 중요
// 리액트에서 랜더링은 현재 props와 state의 상태에 기초하여
// UI구성을 어떻게 구성할지 컴포넌트에게 요청하는 작업을 의미
// triggering -> rendering -> commit 순으로 진행
// 브라우저 랜더링은 다른 프로세스로 페인팅 이라고도 부름
import Layout from "./components/Layout";
import TodoContainer from "./components/todo/TodoContainer";
const App = () => {
return (
<Layout>
<TodoContainer />
</Layout>
);
};
export default App;
const Layout = ({ children }) => {
return <main className="layout">{children}</main>;
};
export default Layout;
import TodoForm from "./TodoForm";
import TodoList from "./TodoList";
import ExTodoForm from "./ExTodoForm";
import { useState } from "react";
const TodoContainer = () => {
const [todos, setTodos] = useState([
{
id: 1,
title: "ok",
content: "content111",
isDone: false,
},
{
id: 2,
title: "ok2",
content: "content222",
isDone: true,
},
]);
const workingTodos = todos.filter((todo) => !todo.isDone);
const doneTodos = todos.filter((todo) => todo.isDone);
return (
<section>
<h1 className="title">Todo List</h1>
<ExTodoForm setTodos={setTodos} />
<TodoList title="Working" todos={workingTodos} setTodos={setTodos} />
<TodoList title="Done" todos={doneTodos} setTodos={setTodos} />
</section>
);
};
export default TodoContainer;
// 비제어 컴포넌트
const ExTodoForm = ({ setTodos }) => {
const onSubmit = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const title = formData.get("title");
const content = formData.get("content");
// 시작과 끝에 공백 문자를 제거 -> trim()
if (!title.trim() || !content.trim()) {
return alert("no!");
}
const nextTodo = {
id: crypto.randomUUID(),
title,
content,
isDone: false,
};
// useState의 비동기성
setTodos((prevTodos) => [nextTodo, ...prevTodos]);
e.target.reset();
};
return (
<div>
<form onSubmit={onSubmit}>
<input type="text" placeholder="제목" name="title" />
<input type="text" placeholder="내용" name="content" />
<button type="submit">등록</button>
</form>
</div>
);
};
export default ExTodoForm;
// 제어 , 비제어 컴포넌트
// 제어 컴포넌트 : 개발자가 매순간 개입하므로 코드가 많아짐
// 비제어 '' : 한 순간만 개입하여 코드가 단순해짐
// 제어 컴포넌트
import { useState } from "react";
const TodoForm = () => {
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
const onSubmit = (e) => {
e.preventDefault();
console.log(title, content);
};
return (
<div>
<form onSubmit={onSubmit}>
<input
type="text"
placeholder="제목"
value={title}
onChange={(event) => setTitle(event.target.value)}
/>
<input
type="text"
placeholder="내용"
value={content}
onChange={(event) => setContent(event.target.value)}
/>
<button type="submit">등록</button>
</form>
</div>
);
};
export default TodoForm;
import TodoItem from "./TodoItem";
const TodoList = ({ title, todos, setTodos }) => {
return (
<div>
<h2 className="todoListTitle">{title}</h2>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<TodoItem todo={todo} setTodos={setTodos} />
</li>
))}
</ul>
</div>
);
};
export default TodoList;
const TodoItem = ({ todo, setTodos }) => {
const { id, title, content, isDone } = todo;
const deleteTodo = () => {
setTodos((prev) => prev.filter((todo) => todo.id !== id));
};
const toggleTodo = () => {
setTodos((prev) =>
prev.map((todo) =>
todo.id === id ? { ...todo, isDone: !todo.isDone } : todo
)
);
};
return (
<div className="todoCard">
<h3 className="todoTitle">{todo.title}</h3>
<p>{todo.content}</p>
<div>
<button onClick={toggleTodo}>{isDone ? "취소" : "완료"}</button>
<button onClick={deleteTodo}>삭제</button>
</div>
</div>
);
};
export default TodoItem;
.layout {
max-width: 1200px;
min-width: 800px;
margin: 0 auto;
}
.title {
font-size: 2rem;
font-weight: bold;
margin: 1rem 0;
}
.todoListTitle {
font-size: 1.5rem;
font-weight: bold;
margin: 1rem 0;
}
.todoCard {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
border: 1px solid #ccc;
}
.todoTitle {
font-size: 1.5rem;
font-weight: bold;
}
'프로젝트 > 미니 프로젝트' 카테고리의 다른 글
SingleProject_가계부(React) (0) | 2024.05.24 |
---|---|
React 학습 (0) | 2024.05.21 |
SingleProject_React 학습 (리랜더링 및 TodoList 완성) (0) | 2024.05.16 |
SingleProject_State Lifting (0) | 2024.05.08 |
TeamProject_git 명령어 및 팀플 기능 개선 (1) | 2024.05.07 |