todo-list
리액트 환경 세팅(CRA)
컴포넌트 분리 - Header, Input, TodoList, Footer
initialState를 3개 부여(각각의 todo는 title, contents, isDone, id 프로퍼티를 가짐)
todos state를 만들고, 화면에 출력
Input 컴포넌트 안에 input 태그 2개 및 button 태그 하나 -> form 태그를 이용하여 구현
todos의 length로 id값을 부여하면 crud를 하면서 todos의 length값이 달라지기 때문에 데이터가 뒤엉켜 에러가 발생할 수 있다.
따라서 새로고침할 때마다 고유한 값을 가지는 uuid를 부여하는 것이 에러를 줄일 수 있다.
return (
<div>
{/* <header>헤더입니다.</header> */}
<Header>헤더입니다.</Header>
<main
style={{
padding: '20px',
backgroundColor: '#caedd3',
}}
>
{/* 인풋창2개 추가버튼 */}
<Input setTodos={setTodos} />
{/* initialState 출력창 - 진행, 완료 2파트*/}
{/* 진행 isActive */}
<TodoList isActive={true} setTodos={setTodos} todos={todos} />
<TodoList isActive={false} setTodos={setTodos} todos={todos} />
</main>
{/* <footer>푸터입니다.</footer> */}
<Footer>푸터입니다.</Footer>
</div>
);
사용한 컴포넌트
function TodoList({ isActive, setTodos, todos }) {
return (
<div>
<h3>{isActive ? '진행중' : '완료'}</h3>
{/* todos 출력 - 하나씩 뽑아서 진행/ 완료 분리해서 출력 */}
{todos
.filter((item) => item.isDone === !isActive)
.map((item) => {
return (
<div key={item.id}>
<h5>{item.title}</h5>
<p>{item.contents}</p>
<button>{isActive ? '완료' : '취소'}</button>
<button>삭제</button>
</div>
);
})}
</div>
);
}
filter, map 함수에 대해 잘 알아야 중첩사용해도 헷갈리지 않는다.
function Input({ setTodos }) {
const [title, setTitle] = useState('');
const [contents, setContents] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
// 입력창 초기화해준다.
setTitle('');
setContents('');
// 사용자의 행동을 제어해준다.
if (title === '') {
alert('제목을 입력하세요');
return;
}
if (contents === '') {
alert('내용을 입력하세요');
return;
}
// newTodo 만들어서 setTodos에 같이 넣어준다
const newTodo = {
title,
contents,
isDone: false,
id: uuidv4(),
};
setTodos((prev) => {
return [...prev, newTodo];
});
};
const handleTitleChange = (event) => {
setTitle(event.target.value);
};
const handleContentsChange = (event) => {
setContents(event.target.value);
};
return (
<div>
<section>
<form onSubmit={handleSubmit}>
제목: <input value={title} onChange={handleTitleChange} />
내용: <input value={contents} onChange={handleContentsChange} />
<button>추가</button>
</form>
</section>
</div>
);
}
내일 이어서 crud 중에서 나머지 업데이트, 삭제를 추가해주겠다.