1. 처음으로 만들었던 투두리스트 [2023.11.06] 리팩토링 !
https://zerotonine2da.tistory.com/64
2. 개선 내용
1. <form>태그의 onSubmit 사용
2. id값 = uuid 사용
3. Working과 Done부분을 하나의 컴포넌트 로 만들기 --중복 줄이기
- 기존에는 Contents라는 컴포넌트 안에 (Working + Done부분을 2개의 DIV태그로 사용했음)
3. 반영 내용
1. App.jsx
import { useState } from 'react';
import './App.css';
import uuid from 'react-uuid';
import Inputs from './component/Inputs';
import Contents from './component/Contents';
function App() {
const initialState = [
{ id: uuid(), title: '제목1', content: '내용1', isDone: false },
{ id: uuid(), title: '제목2', content: '내용2', isDone: false },
{ id: uuid(), title: '제목3', content: '내용3', isDone: true },
];
const [todos, setTodo] = useState(initialState);
return (
<>
<header></header>
<main>
<Inputs todos={todos} setTodo={setTodo} />
<Contents todos={todos} setTodo={setTodo} isDone={false} />
<Contents todos={todos} setTodo={setTodo} isDone={true} />
</main>
<footer></footer>
</>
);
}
export default App;
▶uuid() 란? 고유한 아이디를 생성할 수 있음
(1) 터미널 : npm install react-uuid / yarn add react-uuid 모듈 설치
(2) import uuid from 'react-uuid'
(3) 원하는 구간에 uuid() 사용
▶ Working과 Done부분을 하나의 컴포넌트 로 만들기 => Contents.jsx로 생성
(isDone값으로 할일/완료일 구분)
2. Contents.jsx
import React from 'react';
function Contents({ todos, setTodo, isDone }) {
return (
<div>
{isDone === true ? '완료목록' : '할일목록'}
{todos
.filter((item) => item.isDone === isDone)
.map((todo) => {
return (
<div key={todo.id} style={{ background: '#538eed', margin: '10px' }}>
<div>{todo.title}</div>
<p>{todo.content}</p>
<button
onClick={() => {
const deleted = todos.filter((item) => {
return item.id !== todo.id;
});
setTodo(deleted);
}}
>
삭제
</button>
<button
onClick={() => {
const stateChange = todos.map((item) => {
return item.id === todo.id ? { ...item, isDone: !item.isDone } : item;
});
setTodo(stateChange);
}}
>
{isDone === true ? '취소' : '완료'}
</button>
</div>
);
})}
</div>
);
}
export default Contents;
▶todos(할일들 리스트).filter( 'isDone:true /false)값에 따라 구분하기)
.map(각각의 할일을 생성)
▶삭제 버튼 : todos(할일들 리스트).filter(삭제버튼 누른 id와 할일(todo)랑 비교-> 안 같은 것들 출력)
+ setTodo로 랜더링
▶취소/완료 버튼 : todos(할일들 리스트).map(삭제버튼과 같이 id값 비교해서-> isDone값 업데이트)
+ {...item, isDone: !item.isDone} 으로 스프레드로 변경 (불변성을 위해)
+ setTodo로 랜더링
3. Inputs.jsx
import React from 'react';
import { useState } from 'react';
import uuid from 'react-uuid';
function Inputs({ todos, setTodo }) {
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
return (
<div>
<form
onSubmit={(event) => {
event.preventDefault();
const newTodo = {
id: uuid(),
title,
content,
isDone: false,
};
setTodo([...todos, newTodo]);
}}
>
제목
<input
value={title}
onChange={(event) => {
setTitle(event.target.value);
}}
></input>
내용
<input
value={content}
onChange={(event) => {
setContent(event.target.value);
}}
></input>
<button>입력하기</button>
</form>
</div>
);
}
export default Inputs;
▶<form> 태그는 onSubmit 속성이 있음, 별 다른 설정이 없으면
<button>이 default로 작동됨.
▶ 일반적신 속성으로 새로고침이 되서 -> event.preventDefault();
끝.