●1_ 데이터의 수정 기능 전략 :
List에 item들에 checkBox를 체크하면, data들의 isDone 속성값의 변경이 적용되도록 한다.
순서1_ App 컴포넌트에 수정 핸들러 작성=> setItems + items.map() + 핸들러의 매개인자 : targetID vs item의 id 비교 후,
일치 => spread 문법 + 변경하고픈 프로퍼티값 toggle / 일치X => 그냥 반환
const onChangeIsDone = (targetID)=>{
setItems(items.map((item)=>{
if(item.id===targetID){
return {
...item,
isDone : !item.isDone,
}
}
return item;
});
);
}
순서2_ onChangeIsDone메소드는 TodoItem 컴포넌트의 checkBox input에서 호출 되어야 하므로, props로 메소드를 TodoItem컴포넌트까지 전달하기
순서3_ onChangeIsDone메소드를 input_CheckBox의 onChange 프로퍼티에 적용하는 것이 아닌, 새로운 onChange 핸들러를 작성하여, 거기에 호출 되도록 한다.
const { id, isDone, content, date } = item; //id 속성도 추출
//checkBox의 onChange 핸들러
const onChangeInput = ()=>{
onChangeIsDone(id);
}
<input onChange={onChange} type="checkbox" checked={isDone} /> //적용
최종코드 :
- App.js
import Editor from "./components/Editor";
import Header from "./components/Header";
import List from "./components/List";
import "./App.css";
import { useState } from "react";
import { useRef } from "react";
const mockdata = [
{
id: 1,
isDone: false,
content: "빨래하기",
date: new Date(),
},
{
id: 2,
isDone: true,
content: "놀기",
date: new Date(),
},
{
id: 3,
isDone: false,
content: "과제하기",
date: new Date(),
},
];
function App() {
const [items, setItems] = useState(mockdata);
const idRef = useRef(mockdata.length);
const onCreateitem = (content) => {
const newItem = {
id: ++idRef.current,
isDone: false,
content: content,
date: new Date(),
};
setItems([newItem, ...items]);
};
const onChangeIsDone = (targetID) => {
setItems(
items.map((item) => {
if (item.id === targetID) return { ...item, isDone: !item.isDone };
return item;
})
);
};
return (
<div className="App">
<Header />
<Editor onCreate={onCreateitem} />
<List onChangeIsDone={onChangeIsDone} items={items} />
</div>
);
}
export default App;
- List.js
import { useState } from "react";
import "./List.css";
import TodoItem from "./TodoItem";
function List({ items, onChangeIsDone }) {
const [search, setSearch] = useState("");
const onChangeSearch = (event) => {
setSearch(event.target.value);
};
const getFilterItems = items.filter((item) => {
return item.content.toLowerCase().includes(search.toLowerCase());
/* 여기 까먹었었음음 */
});
return (
<div className="List">
<p>Todo List🌱</p>
<input
onChange={onChangeSearch}
value={search}
placeholder="검색어를 입력하세요."
/>
<div className="Lists">
{getFilterItems.map((item) => {
return (
<TodoItem
key={item.id}
item={item}
onChangeIsDone={onChangeIsDone}
/>
);
})}
</div>
</div>
);
}
export default List;
- TodoItem
import "./TodoItem.css";
function TodoItem({ item, onChangeIsDone }) {
const { id, isDone, content, date } = item;
const onChange = () => {
onChangeIsDone(id);
};
return (
<div className="TodoItem">
<input onChange={onChange} type="checkbox" checked={isDone} />
<p className="TodoItem-title">{content}</p>
<p className="TodoItem-date">{date.toLocaleDateString()}</p>
<button>삭제</button>
</div>
);
}
export default TodoItem;
●2_ 데이터의 삭제 기능 전략 :
순서1_ 검색 기능과 마찬가지로, App컴포넌트에 삭제 함수 구현 :
setItems + item.filter() 메소드 + 삭제함수 매개인자 targetID !== item.id ★ id와 일치하지 않는 애들만, 포함시킨다.
const onDeleteItem = (targetID) => {
setItems(
items.filter((item) => {
if (item.id !== targetID) return item;
})
);
};
순서2_ 나머지는 checkBox 기능과 논리 동일
TdoItem.js
import "./TodoItem.css";
function TodoItem({ item, onChangeIsDone, onDeleteItem }) {
const { id, isDone, content, date } = item;
const onChange = () => {
onChangeIsDone(id);
};
//삭제 버튼 onCLikck 핸들러
const onClickDelete = () => {
onDeleteItem(id);//App 컴포넌트에서 작성한 onDelete 메소드 호출
};
return (
<div className="TodoItem">
<input onChange={onChange} type="checkbox" checked={isDone} />
<p className="TodoItem-title">{content}</p>
<p className="TodoItem-date">{date.toLocaleDateString()}</p>
<button onClick={onClickDelete}>삭제</button>
</div>
);
}
export default TodoItem;
끝