본문 바로가기
WWWEB/react(&작심삼주)

(react-ToDoList) 에디팅, 필터링 기능 추가

by 미니토이 2024. 12. 4.

Edit기능 추가

  1. <App />에 editTask()함수 추가
    : 배열에서 삭제 대신 변경된 배열을 반환하기 위해 editTask 내 Array.prototype.filter() 대신 Array.prototype.map() 사용
  2. 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

  1. import 문 추가
  2. Todo(props){} 컴포넌트 맨 위에 isEditing 상태를 false로 설정 후 추가
  3. 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 />템플릿 토글링

  1. viewTemplate에서 "편집" 버튼 업데이트
  2. 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
반응형

댓글