9-7. 항목 삭제 기능 구현하기.

송한솔·2023년 6월 7일
0

ReactStudy

목록 보기
53/54

이번에는 지우기 기능을 구현해보겠습니다.
리액트 컴포넌트에서 배열의 불변성을 지키면서 배열 원소를 제거해야 할 경우
배열의 내장함수인 filter를 사용하면 매우 간편합니다.

App.js에 onRemove 함수를 추가해봅시다.
그리고 onInsert와 똑같이 TodoList에 props를 통해 onRemove함수를 전달해주세요.

const onRemove = useCallback(
  id => {
  	setTodos(todos.filter(todo => todo.id !== id));
  },
  [todos],
);
...
...
  	<TodoList todos = {todos} onRemove = {onRemove}/>
...

App.js

// App.js
import './reset.css';
import { useState, useCallback, useRef } from 'react';
import TodoInsert from "./components/TodoInsert";
import TodoTemplate from "./components/TodoTemplate";
import TodoList from './components/TodoList';

function App() {
  const [todos, setTodos] = useState([
    {
      id: 1,
      text: "리액트 기초 알아보기",
      checked: true,
    },
    {
      id: 2,
      text: "컴포넌트 스타일링해 보기",
      checked: true,
    },
    {
      id: 3,
      text: "일정관리 앱 시작하기",
      checked: false,
    },
  ]);

  /// 고유값으로 사용할 id => ref를 사용하여 변수 담기
  const nextId = useRef(4);
  
  // 항목을 추가할 onIsert 함수 생성
  const onInsert = useCallback(text => {
      const todo = {
        id: nextId.current,
        text,
        checked: false,
      };
      setTodos(todos.concat(todo));
      nextId.current += 1; // nextId 1씩 더하기
    },
    [todos]
  );// 의존성 배열 ▼
  // todos가 변경될 때마다 새로운 함수가 생성됩니다.
  // 따라서, onInsert 함수는 항상 최신의 todos 배열을 참조하게 됩니다.

  // 항목 제거기능 구현
  const onRemove = useCallback(
    id => {
      setTodos(todos.filter(todo => todo.id !== id));
    },
    [todos],
  );

  return (
    <div>
      <TodoTemplate>
        <TodoInsert onInsert={onInsert}/> {/* 생성한 onInsert를 TodoInsert의 props로 설정 */}
        <TodoList todos = {todos} onRemove = {onRemove}/>
      </TodoTemplate>
    </div>
  );
}

export default App;

TodoList.js

방금과 같은 과정을 거쳐 TodoListItem에서 onRemove를 사용하기 위해서 props를 통해 전달해주세요.

// TodoList.js
import TodoListltem from "./TodoListltem";
import "./TodoList.css";

const TodoList = ({ todos, onRemove }) => {
    return (
        <section className="TodoList">
            {todos.map(item => (
                <TodoListltem todo={item} key={item.id} onRemove={onRemove}/>
            ))}
        </section>
    );
};

export default TodoList;

TodoListltem.js

// TodoListltem.js
import {
    MdCheckBoxOutlineBlank,
    MdCheckBox,
    MdRemoveCircleOutline
} from "react-icons/md";
import "./TodoListItem.css";
import cn from "classnames";

const TodoListltem = ({ todo, onRemove }) => {
    const { id, text, checked } = todo;

    return (
        <section className='TodoListItem'>
            <div className={cn("checkbox", { checked })}>
                {checked ?<MdCheckBox/>: <MdCheckBoxOutlineBlank/>}
                <div className="text">{text}</div>
            </div>
            <div className="remove" onClick={() => onRemove(id)}>
                <MdRemoveCircleOutline/>
            </div>
        </section>
    );
};

export default TodoListltem;

props를 통해 받아온 todo 배열에 id를 추가하고 추가한 id를 onRemove의 매개변수로 넣어주세요.

클릭한 항목의 id를 filter를 통해서 id를 제외한 항목만 남김으로써 제거할 수 있습니다.

결과

오른쪽의 빨간 버튼을 누르면 추가한 항목이 삭제되는것을 볼 수 있습니다.

0개의 댓글