Edit기능 추가
- <App />에 editTask()함수 추가
: 배열에서 삭제 대신 변경된 배열을 반환하기 위해 editTask 내 Array.prototype.filter() 대신 Array.prototype.map() 사용 - editTask를 <Todo /> 컴포넌트 prop으로 전달 (deleteTask와 동일한 방식)
// #스텝1: <App />에 editTask()함수 추가
function editTask(id, newName) {
const editedTaskList = tasks.map((task) => {
// if this task has the same ID as the edited task
if (id === task.id) {
// Copy the task and update its name
return { ...task, name: newName };
}
// Return the original task if it's not the edited task
return task;
});
setTasks(editedTaskList);
}
// #스텝2: editTask를 <Todo /> 컴포넌트 속성으로 전달
const taskList = tasks.map((task) => (
<Todo
id={task.id}
name={task.name}
completed={task.completed}
key={task.id}
toggleTaskCompleted={toggleTaskCompleted}
deleteTask={deleteTask}
editTask={editTask}
/>
));
Todo.jsx
- import 문 추가
- Todo(props){} 컴포넌트 맨 위에 isEditing 상태를 false로 설정 후 추가
- Edit기능 템플릿 만들기 (Todo()함수의 useState() 훅 아래, return문 위에 삽입)
// #스텝1: useState를 Todo 컴포넌트로 가져오기
import React, { useState } from "react";
// #스텝2: Todo(props){} 컴포넌트의 맨 위에 const 추가
const [isEditing, setEditing] = useState(false);
// #스텝3: Edit기능 템플릿 만들기 (Todo()함수의 useState() 훅 아래, return문 위에 삽입)
const editingTemplate = (
<form className="stack-small">
<div className="form-group">
<label className="todo-label" htmlFor={props.id}>
{props.name}의 새로운 이름
</label>
<input id={props.id} className="todo-text" type="text" />
</div>
<div className="btn-group">
<button type="button" className="btn todo-cancel">
취소
<span className="visually-hidden">{props.name} 이름 바꾸기</span>
</button>
<button type="submit" className="btn btn__primary todo-edit">
저장
<span className="visually-hidden">{props.name}의 새로운 이름</span>
</button>
</div>
</form>
);
const viewTemplate = (
<div className="stack-small">
<div className="c-cb">
<input
id={props.id}
type="checkbox"
defaultChecked={props.completed}
onChange={() => props.toggleTaskCompleted(props.id)}
/>
<label className="todo-label" htmlFor={props.id}>
{props.name}
</label>
</div>
<div className="btn-group">
<button type="button" className="btn">
편집 <span className="visually-hidden">{props.name}</span>
</button>
<button
type="button"
className="btn btn__danger"
onClick={() => props.deleteTask(props.id)}>
삭제 <span className="visually-hidden">{props.name}</span>
</button>
</div>
</div>
);
코드를 살펴보면 Todo()함수 내에 2개의 템플릿 구조(edit, view)가 const 내 정의가 됨.
즉, <Todo />의 return문이 반복된다는 것을 의미.
조건에 따른 렌더링
jsx에서 삼항 연산자를 통해 조건문을 작성할 수 있음.
<Todo />컴포넌트에서 edit 하고 있는지를 체크해야 하기 때문에 Todo() 함수 내에 return문을 수정해줌.
// #Todo() 안에 return문을 삼항연산자로 수정
return <li className="todo">{isEditing ? editingTemplate : viewTemplate}</li>;
[참고] 삼항연산자란?
: 조건에 따라 다른 값을 반환하는 간결한 표현 방식을 제공하는 연산자로 if-else 문을 한 줄로 표현.
// #삼항연산자 문법
조건 ? 참일 때 값 : 거짓일 때 값
// #삼항연산자 예시
let age = 25;
let isAdult = age >= 19 ? "성인" : "미성년";
console.log(isAdult); // 조건이 참이기 때문에 "성인" 출력
<Todo />템플릿 토글링
- viewTemplate에서 "편집" 버튼 업데이트
- editingTemplate의 "Cancel" 버튼 업데이트
// #스텝1: 유저가 viewTemplate에서 "Edit"을 누를 때 true로 setEditing() 호출하여 템플릿 전환
<button type="button" className="btn" onClick={() => setEditing(true)}>
편집 <span className="visually-hidden">{props.name}</span>
</button>
// #스텝2: isEditing을 false로 설정하여 뷰 템플릿으로 전환
<button
type="button"
className="btn todo-cancel"
onClick={() => setEditing(false)}>
취소
<span className="visually-hidden">{props.name} 이름 바꾸기</span>
</button>
728x90
반응형
'WWWEB > react(&작심삼주)' 카테고리의 다른 글
(react) 작업된 소스 합치기 (4) | 2024.11.27 |
---|---|
(react) Events & state 처리해보기 (1) | 2024.11.26 |
(react) 컴포넌트 만들기4 (0) | 2024.11.25 |
(react) 반복작업 줄이기 (0) | 2024.11.24 |
(react) 컴포넌트 만들기 2 (0) | 2024.11.23 |
(react) 컴포넌트로 만들기 (0) | 2024.11.22 |
(react) Todo List App 단계별 만들기 (0) | 2024.11.21 |
(react) create react app (1) | 2024.11.20 |
댓글