훈돌라
2024. 5. 16 리액트 과제 제출 본문
투두리스트 만들기,, 필수 조건들만 겨우 겨우 완성해서 제출할 수 있었다.
뭐가 이렇게 어려운지,, 바닐라로 했으면 뚝딱 만들었을 것 같은데 리액트로 하려니 너무 어렵네..
import React, { useState } from 'react';
//todo 아이템 스타일
const todoinstyle = {
width: '300px',
height: '200px',
border: '3px solid red',
borderRadius: '10px',
marginLeft: '10px',
};
//todo 추가 폼 컨포넌트
const SubmitForm = ({ onAddItem }) => {
const [name, setName] = useState('');
const [nameco, setNameco] = useState('');
const handleSubmit = () => {
onAddItem({ title: name, content: nameco });
setName('');
setNameco('');
};
return (
<div className='subbmit' style={{ width: '700px', display: 'flex', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', backgroundColor:"grey" }}>
<input type='text' placeholder='제목' value={name} onChange={(e) => setName(e.target.value)} className='name'></input>
<input type='text' placeholder='내용' style={{ margin: '10px' }} value={nameco} onChange={(e) => setNameco(e.target.value)} className='nameco'></input>
<button onClick={handleSubmit} className='gobtn'>제출</button>
</div>
);
};
//todoitem 폼 컨포넌트
const ToDoItem = ({ id, title, content, onDelete, onComplete }) => {
const handleDelete = () => {
onDelete(id);
};
const handleComplete = () => {
onComplete(id);
};
return (
<div className='todoin' style={todoinstyle}>
<div className='todotext' style={{ paddingLeft: '20px' }}>
<h2>{title}</h2>
<p style={{ height: '50px' }}>{content}</p>
</div>
<div className='btn' style={{ textAlign: 'center', paddingTop: "10px"}}>
<button onClick={handleDelete}>삭제하기</button> <button onClick={handleComplete}>완료</button>
</div>
</div>
);
};
//doneitem 폼 컨포넌트
const DoneItem = ({ id, title, content, onCancel, onDelete }) => {
const doneHandleDelete = () => {
onDelete(id);
};
const handleCancel = () => {
onCancel(id);
};
return (
<div className='donein' style={todoinstyle}>
<div className='donetext' style={{ paddingLeft: '20px' }}>
<h2>{title}</h2>
<p style={{ height: '50px' }}>{content}</p>
</div>
<div className='btn' style={{ textAlign: 'center',paddingTop: "10px" }}>
<button onClick={doneHandleDelete}>삭제하기</button> <button onClick={handleCancel}>취소</button>
</div>
</div>
);
};
//앱 컴포넌트
const App = () => {
const [todoItems, setTodoItems] = useState([]);
const [doneItems, setDoneItems] = useState([]);
//todo 추가 함수 // newItem 객체를 받아와서 현재 todoItems 배열에 추가하고, 각 항목에 고유한 id를 할당하여 저장함
const handleAddItem = (newItem) => {
setTodoItems([...todoItems, { ...newItem, id: todoItems.length }]);
};
//todo 삭제 함수 // id와 일치하지 않는 항목들만 필터링하여 새로운 todoItems 배열로 설정
const handleDeleteItem = (id) => {
setTodoItems(todoItems.filter((item) => item.id !== id));
};
//todo 완료 함수 // 해당 항목을 doneItems 배열에 추가하고, todoItems 배열에서는 해당 항목을 제거
const handleCompleteItem = (id) => {
const itemToComplete = todoItems.find((item) => item.id === id);
setDoneItems([...doneItems, itemToComplete]);
setTodoItems(todoItems.filter((item) => item.id !== id));
};
//완료 -> 취소 함수 // id를 가진 항목을 doneItems 배열에서 제거하고, 해당 항목을 todoItems 배열에 추가
const handleCancelItem = (id) => {
const itemToCancel = doneItems.find((item) => item.id === id);
setTodoItems([...todoItems, itemToCancel]);
setDoneItems(doneItems.filter((item) => item.id !== id));
};
//완료 상태에서 삭제하는 함수 -> id를 가진 항목을 doneItems 배열에서 제거
const doneHandleDelete = (id) => {
setDoneItems(doneItems.filter((item) => item.id !== id));
};
return (
<div style={{ width: '1200px', height: '800px', margin: '0 auto', padding: '20px', display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column' }}>
<SubmitForm onAddItem={handleAddItem} />
<div className='todobox'>
<h1>Working..!</h1>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<ToDoItem title="해야 할 일" content="상단 인풋에 제목과, 내용을 기입하고 제출 버튼을 누르시면 이 포스트 옆에 카드가 생성됩니다." />
{todoItems.map((item) => (
<ToDoItem key={item.id} id={item.id} title={item.title} content={item.content} onDelete={handleDeleteItem} onComplete={handleCompleteItem} />
))}
</div>
</div>
<div className='donebox'>
<h1>Done..!</h1>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<DoneItem title="완료한 일" content="삭제하기 버튼 클릭 시 카드가 삭제되고, 취소 버튼 클릭 시 카드가 해야 할 일 리스트로 돌아갑니다."/>
{doneItems.map((item) => (
<DoneItem key={item.id} id={item.id} title={item.title} content={item.content} onDelete={doneHandleDelete} onCancel={handleCancelItem} />
))}
</div>
</div>
</div>
);
};
export default App;
코드는 이렇게 짜긴 했는데 내가 짰음에도 다시 보려니 너무 막막하다.
그래서 계속 곱씹으면서 다시 쳐보기도 하고, 여러번 복습하는 중이다.
컴포넌트의 존재와, 그 이유, 장점들은 이해할 수 있는데 useState 같은 리액트 함수들이 등장하면서내 뇌가 터져버릴 것 같다..
우선 자바 스크립트 기초 문법을 익히기 위해 분반 수업을 듣고 있는데, 점차 감이 잡힐 것 같기도 하고,,
<body>
<div id="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<script src="script.js"></script>
</body>
const container = document.getElementById('container');
container.addEventListener('click', function(event) {
if (event.target.tagName === 'DIV' && event.target.classList.contains('box')) {
event.target.classList.add('clicked');
//논리연산자 -> div 와 클래스명이 box 라면 -> clicked 클래스를 추가한다
}
});
function getSquare(number) {
return number * number;
}
const result = getSquare(5);
console.log(result); // 25 출력 (5의 제곱)
function getSquare(number) {
return number * number;
}
const result = getSquare(5);
console.log(result); // 25 출력 (5의 제곱)
window.addEventListener("scroll", () => {
console.log({ scrollY });
})
for (let i = 1; i <= 10; i++) {
console.log(i);
}
for (let i = 1; i <= 20; i++) {
if (i % 2 === 0) {
console.log(i);
}
}
setTimeout(() => {
console.log("3초 후에 출력되는 텍스트 입니다")
}, 3000);
let count = 0;
const interval = setInterval(() => {
count++;g
document.getElementById('counter').innerText = count;
if (count === 5) {
console.log('종료');
clearInterval(interval);
}
}, 1000);
알고리즘 풀듯이, 문제 풀이를 하다 모르는 부분이 있으면 강의 자료를 다시 보면서 충분히 풀 수 있는 난이도였다. 확실히 베이직반을 선택한 것 신의 한수인 것 같다.. 아직 자바 스크립트 기초도 어색한데 리액트는 무슨,, 기초부터 확실하게 다지자.