let's get IT with DAVINA 💻
React로 TodoApp 만들기 (3)Delete,Update 기능 개발 본문
1. 먼저, 해당 글을 누르면 ⊕버튼 눌렀을 때 뜨는 창이 나오게 해야겠지?!
- TodoItem.js
- 특정 글을 누르니까 여기서({text}있는 부분=글을 눌렀을때) onClick함수 추가해줘!
import React from "react";
import { MdCheckBox, MdCheckBoxOutlineBlank } from "react-icons/md";
import "./TodoItem.css";
const TodoItem = ({
todo,
onCheckToggle,
onInsertToggle,
onChangeSelectedTodo,
}) => {
const { id, text, checked } = todo;
return (
<div className='TodoItem'>
<div className={`content ${checked ? "checked" : ""}`}>
{checked ? (
<MdCheckBox
onClick={() => {
onCheckToggle(id);
}}
/>
) : (
<MdCheckBoxOutlineBlank
onClick={() => {
onCheckToggle(id);
}}
/>
)}
<div
className='text'
onClick={() => { //3. ❗️ 이 부분 추가!!
onChangeSelectedTodo(todo); //그러면 사용자가 선택한 글이 setSelectedTodo의 값이 돼!
onInsertToggle();
}}
>
{text}
</div>
</div>
</div>
);
};
export default TodoItem;
- App.js
import React, { useState } from "react";
import { MdAddCircle } from "react-icons/md";
import "./App.css";
import Template from "./components/Template";
import TodoInsert from "./components/TodoInsert";
import TodoList from "./components/TodoList";
let nextId = 4;
const App = () => {
const [selectedTodo, setSelectedTodo] = useState(null); //1. ❗️이 부분 추가
const [insertToggle, setInsertToggle] = useState(false);
const [todos, setTodos] = useState([
{
id: 1,
text: "할일 1",
checked: true,
},
{
id: 2,
text: "할일 2",
checked: false,
},
{
id: 3,
text: "할일 3",
checked: true,
},
]);
const onInsertToggle = () => {
if (selectedTodo) {
setSelectedTodo(null);
}
setInsertToggle((prev) => !prev);
};
const onInsertTodo = (text) => {
if (text === "") {
return alert("할 일을 입력해주세요.");
} else {
const todo = {
id: nextId,
text,
checked: false,
};
setTodos((todos) => todos.concat(todo)); //상태 불변성 유지 push 대신 concat
nextId++;
}
};
const onCheckToggle = (id) => {
setTodos((todos) =>
todos.map((todo) =>
todo.id === id ? { ...todo, checked: !todo.checked } : todo
)
);
};
const onChangeSelectedTodo = (todo) => { //2. ❗️이 부분 추가
setSelectedTodo(todo);
};
const onRemove = (id) => {
onInsertToggle();
setTodos((todos) => todos.filter((todo) => todo.id !== id));
};
const onUpdate = (id, text) => {
onInsertToggle();
setTodos((todos) =>
todos.map((todo) => (todo.id === id ? { ...todo, text } : todo))
);
};
return (
<Template todoLength={todos.length}>
<TodoList
todos={todos}
onCheckToggle={onCheckToggle}
onInsertToggle={onInsertToggle}
onChangeSelectedTodo={onChangeSelectedTodo}
/>
<div className='add-todo-button' onClick={onInsertToggle}>
<MdAddCircle />
</div>
{insertToggle && (
<TodoInsert
selectedTodo={selectedTodo}
onInsertToggle={onInsertToggle}
onInsertTodo={onInsertTodo}
onRemove={onRemove}
onUpdate={onUpdate}
/>
)}
</Template>
);
};
export default App;
2. ⊕추가 모달창과 수정용 모달창은 다르게 해야겠지?
- 새롭게 추가하는게 아닌, 기존 글을 띄운 상태로 그걸 수정하도록..
- TodoInsert.js
import React, { useEffect, useState } from "react";
import { MdAddCircle } from "react-icons/md";
import { TiTrash, TiPencil } from "react-icons/ti";
import "./TodoInsert.css";
const TodoInsert = ({
onInsertToggle,
onInsertTodo,
selectedTodo,
onRemove,
onUpdate,
}) => {
const [value, setValue] = useState("");
const onChange = (e) => {
setValue(e.target.value);
};
const onSubmit = (e) => {
e.preventDefault();
onInsertTodo(value);
setValue("");
onInsertToggle();
};
useEffect(() => { //❗️ 1. 이 부분 추가! 받아온(선택된) todo의 text값으로 value값 바꿔주라
if (selectedTodo) {
setValue(selectedTodo.text);
}
}, [selectedTodo]);
return (
<div>
<div className='background' onClick={onInsertToggle}></div>
<form
onSubmit={
selectedTodo
? () => {
onUpdate(selectedTodo.id, value); //❗️ 4. 선택한 글의 id와 변경된 value로 update함수에 넣어주기
}
: onSubmit
}
>
<input
placeholder='add your to-do'
value={value}
onChange={onChange}
></input>
{selectedTodo ? ( //❗️ 2. selectedTodo가 있으면 수정용 모달창
<div className='rewrite'>
<TiPencil
onClick={() => {
onUpdate(selectedTodo.id, value); //❗️ 5. 선택한 글의 id와 변경된 value로 update함수에 넣어주기
}}
/>
<TiTrash onClick={() => onRemove(selectedTodo.id)} />
</div>
) : ( //❗️ 3. selectedTodo가 없으면 추가용 모달창
<button type='submit'>
<MdAddCircle />
</button>
)}
</form>
</div>
);
};
export default TodoInsert;
- App.js
- 수정용 함수와 제거용 함수 만들기
const onInsertToggle = () => {
if (selectedTodo) {
setSelectedTodo(null);
}
setInsertToggle((prev) => !prev);
};
const onRemove = (id) => {
onInsertToggle();
setTodos((todos) => todos.filter((todo) => todo.id !== id));
};
const onUpdate = (id, text) => {
onInsertToggle();
setTodos((todos) =>
todos.map((todo) => (todo.id === id ? { ...todo, text } : todo))
);
};
return (
...생략
🚫 여기서!! onInsertToggle에
if (selectedTodo) { setSelectedTodo(null); }를 추가해주는 이유!?
특정 글을 눌러 수정을 하다 말고, ⊕버튼으로 글 추가할 때 모달창에 수정용 모달창이 그대로 남아있기때문에!
selectedTodo가 있을 경우에는 setSelectedTodo를 null값으로 변경해 초기화시키고
아닌 경우, InsertToggle이 그대로 true/false값 변경되어서 창 열고닫기 해주기!
'DEV_IN > React' 카테고리의 다른 글
React Query (2) | 2023.03.24 |
---|---|
React로 TodoApp 만들기 (2)Create 기능 개발 (2) | 2023.03.02 |
React로 TodoApp 만들기 (1)Setup (4) | 2023.03.02 |
JSX (2) | 2023.02.21 |
What is React? (3) | 2023.02.21 |
Comments