기술/React

[React] 프로젝트 ▶ TodoList ▶ Delete - 삭제하기 + (최종)

leedaramji 2024. 3. 26. 05:39

 

[App 컴포넌트]

import './App.css'
import { useState, useRef } from 'react';
import Editor from './components/Editor'
import Header from './components/Header'
import List from './components/List'

const mockData = [
  {
    id: 0,
    isDone: false,
    content: "콩두부 산책하기",
    date: new Date().getTime(),
  },
  {
    id: 1,
    isDone: false,
    content: "명상하기",
    date: new Date().getTime(),
  },
  {
    id: 2,
    isDone: false,
    content: "코딩하기",
    date: new Date().getTime(),
  },
];

function App() {
  const [todos, setTodos] = useState(mockData);
  const idRef = useRef(3);

  const onCreate = (content) => {
    const newItem = {
      id: idRef.current++,
      content,
      isDone: false,
      Date: new Date().getTime(),
    };

    setTodos([newItem, ...todos]);
  }
  // 인수: todos 배열에서 targetId와 일치하는 id를 갖는 요소의 데이터만 딱 바꾼 새로운 배열
  const onUpdate = (targetId) => {
    setTodos(todos.map((todo) => todo.id === targetId ? { ...todo, isDone: !todo.isDone } : todo));
  };
  // 매개변수로 삭제할 아이템의 targetId 받아오기
  // 해당 targetId를 갖는 것을 todos State로부터 제거해주면 된다.
  const onDelete = (targetId) => {
    // 인수: todos 배열에서 targetId와 일치하는 id를 갖는 요소만 삭제한 새로운 배열을 넣는다.
    setTodos(todos.filter((todo) => todo.id !== targetId));
    // 기존 요소에서 조건을 만족하는 요소만 제외하고 나마지 요소들만 filter
    // 모든 todo를 순차적으로 순회를 하면서
    // 삼항 연산자로 todo의 id 값이 targetId와 같지 않은 것만 필터링 하도록 만든다.
    // 즉, 삭제 되어야 하는 아이템만 제외하고 새로운 배열을 만들어서 인수로 전달
  }

  return (
    <div className="App">
      <Header />
      <Editor onCreate={onCreate} />
      <List todos={todos} onUpdate={onUpdate} onDelete={onDelete} />
    </div>
  )
}

export default App;

 

[Header 컴포넌트]

import "./Header.css";

const Header = () => {
    return (
        <div className='Header'>
            <h3>TODAY💛</h3>
            <h1>{new Date().toDateString()}</h1>
        </div>
    );
}

export default Header;

[Editor 컴포넌트]

import "./Editor.css";
import { useState, useRef } from 'react';

const Editor = ({ onCreate }) => {
    const [content, setContent] = useState("");
    const inputRef = useRef();

    const onChangeContent = (e) => {
        setContent(e.target.value);
    };

    const onKeyDown = (e) => {
        if (e.keyCode === 13) {
            onSubmit();
        }
    }

    const onSubmit = () => {
        if (!content) {
            inputRef.current.focus();
            return
        }
        onCreate(content);
        setContent("");
    }

    return (
        <div className="Editor">
            <input
                ref={inputRef}
                value={content}
                onChange={onChangeContent}
                onKeyDown={onKeyDown}
                placeholder='새로운 Todo를 입력해주세요.'
            />
            <button onClick={onSubmit}>추가</button>
        </div>
    );
}

export default Editor;

 

 

[List 컴포넌트]

import { useState } from 'react';
import "./List.css";
import TodoItem from './TodoItem';

const List = ({ todos, onUpdate, onDelete }) => {
    const [search, setSearch] = useState("");

    const onChangeSearch = (e) => {
        setSearch(e.target.value);
    }

    const getFilteredData = () => {
        return search === "" ? todos : todos.filter((todo) => todo.content.toLowerCase().includes(search.toLowerCase()));
    };

    const filteredTodos = getFilteredData();

    return (
        <div className='List'>
            <h4>Todo List 🏠</h4>
            <input value={search} onChange={onChangeSearch} placeholder='검색어를 입력하세요' />
            <div className='todos_wrapper'>
                {filteredTodos.map((todo) => {
                    return (
                        <TodoItem
                            key={todo.id}
                            {...todo}
                            onUpdate={onUpdate}
                            onDelete={onDelete}
                        />
                    );
                })}
            </div>
        </div>
    );
}

export default List;

 

 

[TodoItem 컴포넌트]

import "./TodoItem.css";

const TodoItem = ({ id, isDone, content, date, onUpdate, onDelete }) => {
    const onChangeCheckbox = () => {
        onUpdate(id);
    };

    const onClickDeleteButton = () => {
        onDelete(id);
    }
    return (
        <div className='TodoItem'>
            <input onChange={onChangeCheckbox} checked={isDone} type='checkbox' />
            <div className='content'>{content}</div>
            <div className='date'>{new Date().toLocaleDateString()}</div>
            <button onClick={onClickDeleteButton}>삭제</button>
        </div>
    )
}

export default TodoItem;

 

'기술 > React' 카테고리의 다른 글

Vite  (0) 2024.03.28
[React] 프로젝트 ▶ TodoList ▶ 요구사항 분석, 컴포넌트 분리, UI 구현  (0) 2024.03.21
[React] 이벤트 처리하기  (0) 2024.02.27
[React] 컴포넌트  (0) 2024.02.27
[React] 리액트의 데이터 흐름  (0) 2024.02.27