2025.02.03 작성
OS : Window
개발환경 : VScode
개발언어 : JavaScript
프레임워크 : React
const [content, setContent] = useState('');
const idRef = useRef(3);
const onCreate = (content) => {
const newItem = {
id: idRef.current, // 현재 ID 사용
content,
isDone: false,
createDate: new Date().getTime(),
};
setTodo([newItem, ...todo]);
idRef.current += 1; // 다음 ID 값 증가
};
const TodoEditor = ({onCreate}) => { ... }
<TodoEditor onCreate={onCreate} />
import './App.css';
import Header from './component/Header';
import TodoEditor from './component/TodoEditor';
import TodoList from './component/TodoList';
import { useState, useRef } from 'react';
const mockTodo = [
{
id: 0,
isDone: false,
content: "React 공부하기",
createDate: new Date().getTime,
},
{
id: 1,
isDone: false,
content: "빨래 널기기",
createDate: new Date().getTime,
},
{
id: 2,
isDone: false,
content: "노래 연습하하기",
createDate: new Date().getTime,
},
];
function App() {
const idRef = useRef(3);
const [todo, setTodo] = useState(mockTodo);
const onCreate = (content) => {
const newItem = {
id: idRef.current,
content,
isDone: false,
createDate: new Date().getTime(),
};
setTodo([newItem, ...todo]);
idRef.current += 1;
};
return (
<div className="App">
<Header />
<TodoEditor onCreate={onCreate} />
<TodoList />
</div>
);
}
export default App;
import "./TodoEditor.css";
import { useState } from "react";
// props
// {} 쓰면 : 구조분해할당 --> 매개 변수명과 객체의 속성명이 일치하는 값 대입
// 안 쓰면 : 객체 --> onCreate = {onCreate:함수}
const TodoEditor = ({onCreate}) => {
const [content, setContent] = useState('');
const onChangeContent = (e) => {
setContent(e.target.value);
};
return (
<div className="TodoEditor">
<h4>새로운 Todo 작성하기✏️</h4>
<div className="editor_wrapper">
<input placeholder="새로운 Todo..." value={content} onChange={onChangeContent}/>
<button onClick={() => onCreate(content)}>추가</button>
</div>
</div>
);
};
export default TodoEditor;
.TodoEditor .editor_wrapper {
width: 100%;
display: flex;
gap: 10px;
}
.TodoEditor input {
flex: 1;
box-sizing: border-box;
border: 1px solid rgb(220, 220, 220);
border-radius: 5px;
padding: 15px;
}
.TodoEditor input:focus {
outline: none;
border: 1px solid #1f93ff;
}
.TodoEditor button {
cursor: pointer;
width: 80px;
border: none;
background-color: #1f93ff;
color: white;
border-radius: 5px;
}
import TodoItem from "./TodoItem";
import "./TodoList.css"
const TodoList = () => {
return <div className="TodoList">
<h4>Todo List🌱</h4>
<input className="searchbar" placeholder="검색어를 입력하세요" />
<div className="list_wrapper">
<TodoItem />
<TodoItem />
<TodoItem />
</div>
</div>;
};
export default TodoList;
.TodoList .searchbar {
margin-bottom: 20px;
width: 100%;
border: none;
border-bottom: 1px solid rgb(220, 220, 220);
box-sizing: border-box;
padding-top: 15px;
padding-bottom: 15px;
}
.TodoList .searchbar:focus {
outline: none;
border-bottom: 1px solid #1f93ff;
}
.TodoList .list_wrapper {
display: flex;
flex-direction: column;
gap: 20px;
}
import "./TodoItem.css"
const TodoItem = () => {
return (
<div className="TodoItem">
<div className="checkbox_col">
<input type="checkbox" />
</div>
<div className="title_col">할 일</div>
<div className="date_col">{new Date().toLocaleDateString()}</div>
<div className="btn_col">
<button>삭제</button>
</div>
</div>
);
};
export default TodoItem;
.TodoItem {
display: flex;
align-items: center;
gap: 20px;
padding-bottom: 20px;
border-bottom: 1px solid rgb(240, 240, 240);
}
.TodoItem .checkbox_col{
width: 20px;
}
.TodoItem .title_col{
flex: 1;
}
.TodoItem .date_col{
font-size: 14px;
color: gray;
}
.TodoItem .btn_col button {
cursor: pointer;
color: gray;
font-size: 14px;
border: none;
border-radius: 5px;
padding: 5px;
}