본문 바로가기

React

[React] TodoList 만들기(등록,수정,삭제)

 

 

* TodoList 컴포넌트 구조 & 레이아웃

 

 

Todos.js

import React, { useState, useRef } from 'react';
import TodoForm from './TodoForm';
import TodoList from './TodoList';
import './Todos.css'

const Todos = () => {
    // const no = useRef(3)  
    const [data, setData] = useState([
        {id:1, text:'저녁먹기', isChk : false}, 
        {id:2, text:'회사미팅', isChk : false}
    ])

    const no = useRef(data.length + 1)  

    //삭제
    const onDel = (id) => {
        setData(data.filter(item => item.id !== id))
    }

    //추가
    const onAdd = (text) => {
        setData([
            ...data,
            {
                id: no.current++ ,
                text: text,
                isChk : false
            }
        ])
    }

    //수정
    //내가 선택한것은 변경되어야하고 아닌것들은 그대로 돌려주는 조건식
    const onMod = (id) => {
        setData(data.map(item => item.id === id ? {...item, isChk: !item.isChk } : item))
    }

    return (
        <div className='Todos'>
            <h1>TodoList</h1>
            <TodoForm onAdd={onAdd}/>
            <TodoList data={data} onDel={onDel} onMod={onMod}/>
        </div>
    );
};

export default Todos;

 

 

TodoForm.js

import React, { useState, useRef } from 'react';
import './TodoForm.css'

const TodoForm = ({onAdd}) => {
    const [text, setText] = useState('')  //글자가 바뀌는걸 체크해줌
    const textRef = useRef(null)

    const changeInput = (e) => {
        const {value} = e.target  //내가 지정한 값을 바꿈
        setText(value)
    }

    const onSubmit = (e) => {
        e.preventDefault()
        onAdd(text)
        setText('')  // 공백처리
        textRef.current.focus();
    }

    //name은 input이 여러개 일 경우 사용
    return (
        <form className='TodoForm' onSubmit={onSubmit}>
            <input type="text" value={text} onChange={changeInput} 
            placeholder='할일을 입력하세요.' ref={textRef}/> 
            <button>등록</button>
        </form>
    );
};

export default TodoForm;

 

 

TodoList.js

import React from 'react';
import TodoItem from './TodoItem';
import './TodoList.css'

const TodoList = ({data, onDel, onMod}) => {
    return (
        <ul className='TodoList'>
            {
                data.map(item => <TodoItem key={item.id} item={item} 
                    onDel={onDel} onMod={onMod}/>)
            }
        </ul>
    );
};

export default TodoList;

 

 

TodoItem.js

import React from 'react';

const TodoItem = ({item, onDel, onMod}) => {
    const { id, text, isChk } = item
    return (
        <li className={isChk ? 'on' : ''}>
            <span onClick={() => onMod(id)}>&#10003;</span>
            <em>{text}</em>
            <button onClick={() => onDel(id)}>삭제</button>
        </li>
    );
};

export default TodoItem;

 

 

 

TodoForm.css

.TodoForm { text-align: center; padding: 40px 0; background:#d5d1d3;}
.TodoForm input {width:400px; height:45px;padding:0 20px; box-sizing: border-box; vertical-align: top;}
.TodoForm button { width:100px;height:45px;}

 

TodoList.css

.TodoList {}
.TodoList li {padding: 15px 30px; border-bottom: 1px solid #dcdcdc; background: #7c7c7b;; list-style: none;}
.TodoList {padding-left: 0; margin: 0;}
.TodoList li span { margin-right: 20px; font-size: 16px; color:#fff ; cursor: pointer;}
.TodoList li em { color:#fff; cursor: pointer;}
.TodoList li button { float: right; width: 80px; }

.TodoList li.on span { color:yellow }
.TodoList li.on em {color:yellow ; text-decoration: line-through;}

 

Todos.css

.Todos { width: 550px; margin:30px auto;}
.Todos h1 { text-align: center; padding: 30px 0; background: #ff8f8f; margin: 0;}
반응형