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

(react) 작업된 소스 합치기

by 미니토이 2024. 11. 27.

App.jsx

  1. App.jsx에 useState를 가져와서 작업을 상태에 저장하기 위해 App.jsx파일 맨 상단에 import 추가
  2. props.tasks를 useState() 후크에 전달하기 위해 App()함수 내 맨 위에 const ... 선언
  3. props.tasks 대신 task를 매핑한 결과가 되도록 taskList 매핑을 변경 taskList 상수 수정
// #스텝1: useState를 App.jsx에 가져와 상태로 저장하기 위해
import { useState } from "react";

// #스텝2: props.tasks를 useState() hook에 전달하기 위해 App()함수 맨 위에 const... 추가
const [tasks, setTasks] = useState(props.tasks);

// #스텝3: props.tasks 대신 tasks매핑 결과가 되도록 taskList상수 선언 수정
const taskList = tasks?.map((task) => (
  <Todo
    id={task.id}
    name={task.name}
    completed={task.completed}
    key={task.id}
  />
));

 

 

문제점과 수정

  1. addTask() 함수에서 작업 목록 업데이트에 사용하는 setTasks hook이 있는데, 현재 여기서 addTask()의 name 인수를 setTasks로 전달할 수 없는 문제... "tasks는 객체의 배열"이고 "name은 문자열"이기 때문. 
  2. addTask() 함수가 각 작업에 똑같은 ID를 부여하는 문제 → nanoid 라이브러리 사용
  3. 작업 수에 상관없이 제목에 갯수 변경 안 됨  → App()에 taskList 카운팅 및 텍스트 변경처리
// #문제해결1: addTask()함수 내 newTask객체를 만들고 배열에 추가
function addTask(name) {
  const newTask = { id: "id", name, completed: false };
  setTasks([...tasks, newTask]);
}

// #문제해결2-1: 고유 ID를 주기 위해 터미널에서 nanoid 라이브러리 설치
// npm install nanoid 또는 yarn add nanoid

// #문제해결2-2: App.jsx 상단에 import 추가
import { nanoid } from "nanoid";

// #문제해결2-3: addTask()를 업데이트해서 각 작업 ID가 "todo-" + nanoid라이브러리의 문자열이 되도록
const newTask = { id: `todo-${nanoid()}`, name, completed: false };

// #문제해결3-1: App()정의 내부에 추가
const headingText = `${taskList.length} tasks remaining`;

// #문제해결3-2: tasks를 따로 빼기 위해 tasksNoun 생성
const tasksNoun = taskList.length !== 1 ? "tasks" : "task";
const headingText = `${taskList.length} ${tasksNoun} remaining`;

// #문제해결3-3: <h2> 텍스트를 headingText로 수정
<h2 id="list-heading">{headingText}</h2>

 

 

테스팅

  1. App() 컴포넌트에 taskList 상수 선언 바로 윗부분에 toggleTaskCompleted() 함수 생성
  2. taskList 안의 <Todo />컴포넌트의 props에 toggleTaskCompleted 추가
  3. Todo.jsx로 가서 <input />요소에 onChange 이벤트 추가. 
  4. App.jsx에서 toggleTaskCompleted() 함수 수정.
    → tasks 배열에 매핑되는 updatedTasks 상수를 정의,
    작업의 id props가 함수의 id값과 일치하면 새 객체를 만들고 반환 전 해당 객체의 completed props를 토글.
    일치하지 않으면 원래의 객체를 반환
    → 이후 다음 상태를 업데이트하기 위해 새로운 배열로 setTasks()를 호출함
// #스텝1: taskList 상수 선언 바로 위에 toggleTaskCompleted()함수 생성
function toggleTaskCompleted(id) {
  console.log(tasks[0]);
}

// #스텝2: taskList 내부에 <Todo />컴포넌트의 props에 toggleTaskCompleted 추가
const taskList = tasks.map((task) => (
  <Todo
    id={task.id}
    name={task.name}
    completed={task.completed}
    key={task.id}
    toggleTaskCompleted={toggleTaskCompleted}
  />
));

// #스텝3: 익명 함수를 사용해서 props.id 매개변수로 props.toggleTaskCompleted() 호출
<input
  id={props.id}
  type="checkbox"
  defaultChecked={props.completed}
  onChange={() => props.toggleTaskCompleted(props.id)}
/>

// #스텝4: 토글된 작업의 completed props만 변경하기~ App.jsx의 toggleTaskCompleted() 함수 수정
function toggleTaskCompleted(id) {
  const updatedTasks = tasks.map((task) => {
    // if this task has the same ID as the edited task
    if (id === task.id) {
      // use object spread to make a new object
      // whose `completed` props has been inverted
      return { ...task, completed: !task.completed };
    }
    return task;
  });
  setTasks(updatedTasks);
}

 

 

작업 삭제 기능 만들기

  1. toggleTaskCompleted() 아래쪽에 deleteTask() 추가
  2. <Todo />컴포넌트 배열에 다른 콜백 props를 추가
  3. Todo.jsx 내부에 삭제 버튼 수정
  4. deleteTask() 호출이 잘 되는지 확인 후 deleteTask()에서 setTasks() hook 호출을 위해  App.jsx에서 deleteTask() 수정
// #스텝1: App.jsx에서 toggleTaskCompleted() 아래쪽에 deleteTask() 함수 선언
function deleteTask(id) {
  console.log(id);
}

// #스텝2: <Todo /> 컴포넌트 배열에 콜백 props 추가
const taskList = tasks.map((task) => (
  <Todo
    id={task.id}
    name={task.name}
    completed={task.completed}
    key={task.id}
    toggleTaskCompleted={toggleTaskCompleted}
    deleteTask={deleteTask}
  />
));

// #스텝3: Todo.jsx의 삭제버튼 수정
<button
  type="button"
  className="btn btn__danger"
  onClick={() => props.deleteTask(props.id)}>
  Delete <span className="visually-hidden">{props.name}</span>
</button>

// #스텝4: App.jsx의 deleteTask()함수 수정
function deleteTask(id) {
  const remainingTasks = tasks.filter((task) => id !== task.id);
  setTasks(remainingTasks);
}

 

여기까지 하고 삭제 기능이 잘 되는지 확인하니 다행히 이상없이 잘 됨 ㅎㅎ

그럼 오늘은 여기까지~~ ㅎㅎ

 

 

 

 

 

 

더보기

작심삼주 이벤트는 오늘로써 완료! 짝짝짜자작~

이번에 새로 들어간 프로젝트가 react기반이라 눈물콧물땀물 다 흘리면서 겨우겨우 따라가는 나를 발견;;;

react공부를 해야지, 해야지만 하다가 마침 운명의 짝을 만난 것처럼 티스토리에서 오블완 작심3주 이벤트를 하길래

이번 기회에 react 공부를 시작해야겠다 굳게 마음먹고, 꾸준히 공부를 이어나갈 수 있었음~ ㅠㅠ

회사에 육아하는 환경에서 매일 공부를 하면서 글을 올린다는게 저~~엉말 쉽지는 않았지만 그래도 어쨌든 하기는 했으니깐...

혹시 이 글을 읽는 분이라면... 야너두? ㅎㅎㅎ 암튼, 바쁘다 핑계대지 말고 앞으로도 꾸준히 공부를 해나가야 하겠음!

끝이 아닌 계쏙꼐쏚쭉쭊쭊~

 

728x90
반응형

댓글