나의 개발일지

[React] 리액트 입문주차 개인과제 (TodoList 만들기) 본문

과제 및 팀프로젝트

[React] 리액트 입문주차 개인과제 (TodoList 만들기)

heew0n 2023. 11. 3. 21:03

🔥React 입문주차 개인과제 🔥

 

 

다시 돌아온 개인과제 Time~ ^^..

이번엔 끝낼 수 있을지 걱정이다!

강의에서 배운 그대로 해보려고 하는 데도 잘 되지 않는다

일단 진행과정을 코드를 통해 적어볼 계획이다.

 

 

 

✔️ 구현해야 할 기능

· UI 구현하기

· Todo 추가하기

· Todo 삭제하기

· Todo 완료 상태 변경하기 

 

 

 

💡Hint

· 사용한 hook은 오직 useState

· 기능 구현을 위해 생성한 함수는 2개(onChangeHandler, onSubmitHandler)

· 사용한 자바스크립트 내장 메서드는 map, filter

· todo의 initial state는 {id : 0, title: "", body: "", isDone: false}

 

 

 

 

 

▼App.jsx

import React from 'react'
import TodoList from './Pages/TodoList'
import './App.css'

function App() {
    return (
      <TodoList />
    );
  }

  export default App;

 

 

▼pages > TodoList.jsx

import React, {useState} from 'react'
import Layout from '../components/Layout'
import Header from '../components/Header'
import Form from '../components/Form'
import List from '../components/List'

// 부모 컴포넌트
function TodoList() {
    const [todos, setTodos] = useState([
        {// id를 지정해주는 이유는 새로고침해도 화면에 렌더링 돼있어야 하기 때문!
         // 새로 등록하는 id는 Date.now()를 사용하여 겹치는 id가 없도록 한다.
            id: 1,   
            title: "REACT 공부하기",
            content: "강의 다시 듣기",
            isDone: false
        },
        {
            id: 2,
            title: "알고리즘 문제풀기",
            content: "하루에 한 문제는 필수!",
            isDone: true
        }
    ])

    return (
        <Layout>
            <Header />
            <Form todos={todos} setTodos={setTodos}/>
            <List todos={todos} setTodos={setTodos}/>
        </Layout>
    )
}
export default TodoList

 

 

 

 

▼Header.jsx

import React from "react";


function Header() {
    return (
        <div className="header">
            <div className="page_name">My Todo-List</div>
            <div className="subject">React</div>
        </div>
    )
}
export default Header

 

 

 

▼Layout.jsx

import React from 'react'


function Layout(props) {
    return (
        <div className='layout'>
            {props.children}
        </div>
    )
}
export default Layout;

 

 

 

▼Form.jsx

import React, {useState} from "react"


//초기값 (기본세팅)
function Form({todos, setTodos}) {
    const initialState = {id: 0, title: "", content: "", isDone: false}

    const [inputTodo, setInputTodo] = useState(initialState)


    const onChangeHandler=(event)=>{
        const {value, name} = event.target 
        setInputTodo({...inputTodo, [name]: value, id: Date.now()})
    }
    const onSubmitHandler=(event)=>{
        event.preventDefault()
        // 입력 칸에 아무런 내용을 적지 않으면 알럿창이 뜬다
        if(inputTodo.title === "" && inputTodo.content ==="") {
            alert("빈칸을 입력해주세요!")
            return
        } 
        setTodos([...todos, inputTodo])
        setInputTodo(initialState)
    }
   
    return (
        <form onSubmit={onSubmitHandler} className="formBox">
            <div className='inputBox'>
                <h3>제 목</h3>           
                <input type='text' name="title" onChange={onChangeHandler} value={inputTodo.title}/> 
                <h3>내 용</h3> 
                <input type='text' name="content" onChange={onChangeHandler} value={inputTodo.content}/>
            </div>
            <button className="addBtn">추가하기</button>
        </form>
    )
}
export default Form

 

▼Todo.jsx

import { buildQueries } from "@testing-library/react";
import React from "react";

const Todo = ({todo, setTodo, todoDone}) => {
console.log(todo)

    // Todo 삭제하기 
    const clickRemoveHandler = (id) => {
        const newTodo = todo.filter(function(todo){
            return todo.id !== id
        })
        setTodo(newTodo);
    }


    // Todo 완료
    const todoToggleBtnHandler = (id) => {
        const newTodo = todo.map(function(todo){
            if(todo.id){
               todo.idDone = !todo.Done
            } return todo;
        })
        setTodo(newTodo);
    }

    return (
     <> 
     <h3>{todoDone ? "Done" : "Working"}</h3>
     <div className="TodoBox">
        {todo.filter(function(todo){
            // console.log(todo.isDone)
            // console.log(todoDone)
            return true
        }).map((todo) => {
            return (
                <div>   
                <h2>{todo.title}</h2>
                <p>{todo.content}</p>
                <div>
                <div>
                    <button onClick={() => clickRemoveHandler(todo.id)}>삭제하기</button>
                </div>
                <div>
                    <button onClick={() => todoToggleBtnHandler(todo.id)}>완료하기</button>
                    <button onClick={() => todoToggleBtnHandler(todo.id)}>{todo.isDone ? "취소하기" : "완료하기"}</button>
                </div>
                </div>
                </div>
             
            );
            })}
    </div>
   </>
 )
        }      

export default Todo;

 

 

 

 

▼List.jsx

import React from "react"

import Todo from './Todo'

function List({todos, setTodos}) {
    const onRemoveHandler = (id) => {
        const remainedTodos = todos.filter((todo)=>{
            return todo.id !== id
        })
        setTodos(remainedTodos)
    }

    const onCompleteHandler = (id) =>{
        const newTodos = todos.map((todo)=>{
            if (todo.id === id) {
                return {...todo, isDone: !todo.isDone}
            } else {
                return {...todo}
            }
        })
        setTodos(newTodos)
    }

    return (
        <div className="list_section">
            <h1>Working... </h1>
            <div className="todoList">
                {todos.map((todo)=>{
                    if(todo.isDone === false) {
                        return <Todo todo={todo} key={todo.id} setTodos={setTodos} onRemoveHandler={onRemoveHandler} onCompleteHandler={onCompleteHandler}/>
                        }
                    }
                )}
            </div>
            <h1>Done..! </h1>
            <div className="todoList">
                {todos.map((todo)=>{
                        if(todo.isDone === true) {
                            return <Todo todo={todo} key={todo.id} setTodos={setTodos} onRemoveHandler={onRemoveHandler} onCompleteHandler={onCompleteHandler}/>
                            }
                        }
                    )}
            </div>
        </div>
    )
}
export default List