React

[React] ToDo-List

낮에만코딩함 2022. 7. 13. 23:48

React를 이용한 ToDo List를 만들었다. 

 

전체 코드 (App.js)

import React, {Component} from "react";
import "./App.css";
export default class App extends Component{
    state = {
      todoData:[
      ],
      value:""
    }

    btnStyle={
      color:"#fff",
      border: "none",
      padding:"5px 9px",
      borderRadius: "50%",
      cursor: "pointer",
      float:"right"
    }

    getStyle = (completed)=>{
      return{
        padding:"10px",
        borderBottom:"1px #ccc dotted",
        textDecoration: completed ? "line-through" : "none",
        marginTop:"5px",
        marginBottom:"5px"
      }
    }

    handleClick = (id)=>{
      let newTodoData = this.state.todoData.filter(data=>data.id !==id);
      this.setState({todoData:newTodoData});
    }    

    handleChange =(e)=>{
      this.setState({value: e.target.value})
    }

    handleSubmit=(e)=>{
      e.preventDefault();
      let newTodo ={
        id:Date.now(),
        title:this.state.value,
        completed:false,
      };
      this.setState({todoData: [...this.state.todoData, newTodo], value: ""})
    }

    handleCompleteChange=(id)=>{
      let newTodoData = this.state.todoData.map(data=>{
        if(data.id ===id){
          data.completed =!data.completed;
        }
        return data;
      });
      this.setState({todoData: newTodoData});
    }

  render(){
    return(
      <div classsName="container">
        <div className="todoBlock">
          <div className="title">
            <h1>할일목록</h1>
          </div>
          {this.state.todoData.map((data)=>(
            <div style={this.getStyle(data.completed)} key={data.id}>
          <input type="checkbox" defaultChecked={false} onChange={()=> this.handleCompleteChange(data.id)}/>
            {data.title}
          <button style={this.btnStyle} onClick={()=> this.handleClick(data.id)}>X</button>
            </div>
          ))}
          
        <form style={{display:'flex', marginTop:'15px'}} onSubmit={this.handleSubmit}>
          <input type="text" name="value" style={{flex:'10', padding:'5px',}}
           placeholder="해야 할 일을 입력하세요."
           value={this.state.value}
           onChange={this.handleChange}
          />
          <input
            type="submit"
            value="입력"
            className="btn"
            style={{flex:'1'}}
          />
        </form>
        </div>
      </div>
    )
  }
}

 


렌더되는 JSX부분을 보면서 코드 중에 중요한 부분을 살펴보자.

 

 <div classsName="container">
        <div className="todoBlock">
          <div className="title">
            <h1>할일목록</h1>
          </div>
          {this.state.todoData.map((data)=>(
            <div style={this.getStyle(data.completed)} key={data.id}>
          <input type="checkbox" defaultChecked={false} onChange={()=> this.handleCompleteChange(data.id)}/>
            {data.title}
          <button style={this.btnStyle} onClick={()=> this.handleClick(data.id)}>X</button>
            </div>
          ))}
          
        <form style={{display:'flex', marginTop:'15px'}} onSubmit={this.handleSubmit}>
          <input type="text" name="value" style={{flex:'10', padding:'5px',}}
           placeholder="해야 할 일을 입력하세요."
           value={this.state.value}
           onChange={this.handleChange}
          />
          <input
            type="submit"
            value="입력"
            className="btn"
            style={{flex:'1'}}
          />
        </form>
        </div>
      </div>

 

 

 

this.state.todoData.map((data)=>()

todoData들은 map을 통해 하나씩 렌더링 된다.

 

저 data는 자연스럽게 state로 이루어져 있는 todoData 배열 값 하나하나가 된다.

 

그리고 리스트는 각각 title, completed, id를 가진다.

 


 

{this.state.todoData.map((data)=>(
            <div style={this.getStyle(data.completed)} key={data.id}>
          <input type="checkbox" defaultChecked={false} onChange={()=> this.handleCompleteChange(data.id)}/>
            {data.title}
          <button style={this.btnStyle} onClick={()=> this.handleClick(data.id)}>X</button>
            </div>
          ))}

div안에 todo들은 checkbox  data.title  button으로 구성된다.

 

checkbox는 default 값이 false로 되어 있고 onChange에 handleCompleteChange라는 함수가 걸려있다.

 

이 함수는 체크박스의 변화를 통해 투두의 completed 상태를 관리해준다.

 

버튼의 경우 투두를 지우는 역할을 하는데 onClickhandleClick이라는 함수가 걸려있다.

 

이를 통해 그 투두의 id로 filter하여 그 투두가 없는 새로운 리스트로 state를 변경해준다.

 


 

<form style={{display:'flex', marginTop:'15px'}} onSubmit={this.handleSubmit}>
          <input type="text" name="value" style={{flex:'10', padding:'5px',}}
           placeholder="해야 할 일을 입력하세요."
           value={this.state.value}
           onChange={this.handleChange}
          />
          <input
            type="submit"
            value="입력"
            className="btn"
            style={{flex:'1'}}
          />
        </form>

 

form을 통해 새로운 todo를 입력할 수 있다.

 

onSubmit이 되면 handleSubmit이라는 함수가 실행된다.

handleSubmit=(e)=>{
      e.preventDefault();
      let newTodo ={
        id:Date.now(),
        title:this.state.value,
        completed:false,
      };
      this.setState({todoData: [...this.state.todoData, newTodo], value: ""})
    }

 

이 함수를 통해 state인 todoData를 새로고침 없이 추가해준다.

 

더 수정된 버전은 내일 올릴 예정이다.