민희의 코딩일지

[React] React로 ToDo 앱 만들기 (1) 본문

WEB FE/React

[React] React로 ToDo 앱 만들기 (1)

heehminh 2023. 1. 28. 23:07
반응형

소스코드: https://github.com/heehminh/23-React-JS-ToDo

 

GitHub - heehminh/23-React-JS-ToDo

Contribute to heehminh/23-React-JS-ToDo development by creating an account on GitHub.

github.com

 

만들고자 하는 앱의 UI: 


1- 할 일 목록 타이틀 만들기

App.js

import React, {Component} from "react";
import "./App.css";

export default class App extends Component {
  // 클래스형 컴포넌트 안에서는 render 안에 UI를 작성
  render() {
    return(
      <div className="container">
        <div className="todoBlock">
          <div className="title">
            <h1>할 일 목록</h1>
          </div>

        </div>
      </div>
    )
  }
}

 

App.css

body {
  background: aliceblue;
}

.container {
  margin: auto;
  max-width: 600px;
}

.todoBlock {
  padding: 30px;
  margin-top: 50px;
  background: #fff;
  border-radius: 10px;
  box-shadow: -9px 17px 13px rgb(0 0 0 / 16%);
}


2- 할 일 목록 UI 만들기

1) 하나의 목록 JSX 추가하기

<div>
  <input type="checkbox" defaultChecked={false} />
  공부하기
  <button style={this.btnStyle}>x</button>
</div>

2) 하나의 목록 스타일링 CSS 

  • x 버튼 만들기
btnStyle = {
  color: "#fff",
  border: "none",
  padding: "5px 9px",
  borderRadius: "50%",
  cursor: "pointer",
  float: "right",
};
  • 밑줄긋기
getStyle = () => {
  return {
    padding: "10px",
    borderBottom: "1px #ccc dotted",
    textDecoration: "none",
  };
};
<div style={this.getStyle()}>
  <input type="checkbox" defaultChecked={false} />
  공부하기
  <button style={this.btnStyle}>x</button>
</div>


3- Map 메소드를 사용한 할 일 목록 나열

1) 목록 data 만들기

todoData = [
    {
      id: "1", // key: 객체의 unique한 값
      title: "공부하기",
      completed: true,
    },
    {
      id: "2",
      title: "청소하기",
      completed: false,
    }
  ]

2) data 나열하기

{this.todoData.map((data)=>(
  <div style={this.getStyle()} key={data.id}>
    <p>
      <input type="checkbox" defaultChecked={false} />
      {" "}{data.title}
      <button style={this.btnStyle}>x</button>
    </p>
</div>
))}

React에서 데이터를 나열하는 경우 key 속성을 넣어주어야 한다.

JSX Key 속성이란?

키는 React가 변경, 추가 또는 제거된 항목을 식별하는 데 도움을 준다. element에 안정적인 ID를 부여하려면 배열 내부의 요소에 키를 제공해야 한다. React는 Key를 이용하여 어떠한 부분이 바뀌었는지 인식할 수 있다. (가상 돔)

Key에는 유니크한 값을 넣어준다. index도 유니크하지만 리스트가 추가되거나 제거되면 해당 리스트들의 Key값도 바뀌게 되므로 id와 같은 값으로 Key를 지정해준다.


4- Filter 메소드를 사용해서 할 일 목록 지우기

x 버튼 클릭 이벤트 발생 시 함수 호출하기

JSX button 안에 클릭리스너 넣기

<button style={this.btnStyle} onClick={() => this.handleClick(data.id)}>x</button>
handleClick = (id) => {
  let newToDoData = this.todoData.filter(data => data.id !== id)
  console.log("newTodoData",newToDoData)
};

버튼을 클릭하면 클릭한 항목 지우기 (클릭한 항목의 id가 아닌 것들만 남겨두기)

로그에서 보면 클릭한 목록을 보면 지워지긴 했지만 UI 상에선 아무런 변화가 없다.

공부하기 (id: &lsquo;1&rsquo;) 삭제 버튼을 눌렀을 때

React에서 데이터가 변할 때 화면을 다시 렌더링 해주기 위해서는 React State를 사용해야 한다.


5- React State 란?

컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체이다. State가 변경되면 컴포넌트는 Re-Rendering 된다. State는 컴포넌트 안에서 관리된다.

React State 생성하기

state = {
  // Map 메소드를 사용한 할 일 목록 나열 
  todoData : [
    {
      id: "1", // key: 객체의 unique한 값
      title: "공부하기",
      completed: true,
    },
    {
      id: "2",
      title: "청소하기",
      completed: false,
    }
  ],
 };
handleClick = (id) => {
    let newToDoData = this.state.todoData.filter(data => data.id !== id)
    this.setState({todoData: newToDoData});
  };
{this.state.todoData.map((data) => (


6- 할 일 목록 추가하기

1) UI

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

2) 글 입력시 state 변경

state = {
    todoData : [
      ...
    ],
    value: "",
  };

state에 value를 빈 값으로 추가

<input
  type="text"
  name="value"
  style={{flex:"10", padding:"5px"}}
  placeholder="해야할 일을 입력하세요."
  value={this.state.value}
	onChange={this.handleChange}
/>
handleChange = (e) => {
  this.setState({value: e.target.value});
}

3) 입력 버튼 클릭 시 목록에 추가, 입력란에 있던 value 초기화

전개 연산자란? (Spread Operator)

전개 연산자는 ES6에서 새롭게 추가되었으며 특정 객체 또는 배열의 값을 다른 객체, 배열로 복제하거나 옮길 때 사용한다. 연산자 모양은 ... 이다.

a. 배열 조합

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];
const arrWrap = [...arr1, ...arr2, ...arr3]; 
// 1, 2, 3, 4, 5, 6, 7, 8, 9

arr1.push(...arr2);
// 1, 2, 3, 4, 5, 6

b. 객체 조합

const obj1 = {
	a: 'A',
	b: 'B',
};
const obj2 = {
	c: 'C',
	d: 'D',
};
const objWrap = {obj1, obj2};
// 결과
{
	a: 'A',
	b: 'B',
	c: 'C',
	d: 'D',
}

c. 기존 배열을 보존 

const arr1 = [1, 2, 3];
const arr2 = arr1.reverse();

console.log(arr1); // 3, 2, 1
console.log(arr2); // 3, 2, 1

원본 배열까지 역순으로 변경된다.

const arr1 = [1, 2, 3];
const arr2 = [...arr1].reverse();

console.log(arr1); // 1, 2, 3
console.log(arr2); // 3, 2, 1

원본 배열이 유지된다.


7- 마무리 된 일 표시하기 (조건부 삼항 연산자)

1) UI

getStyle = (completed) => {
  return {
    padding: "10px",
    borderBottom: "1px #ccc dotted",
    textDecoration: completed ? "line-through" : "none", // 삼항연산자
  };
};
<div style={this.getStyle(data.completed)} key={data.id}>

삼항연산자를 사용하여 completed가 true면 글 중앙에 선긋기

 

2) 체크박스 클릭해서 완료 상태로 바꾸기

<input 
  type="checkbox" 
  onChange= {() => this.handleCompleteChange(data.id)}
  defaultChecked={false} />
handleCompleteChange = (id) => {
  let newToDoData = this.state.todoData.map((data) => {
    if (data.id === id) {
      data.completed = !data.completed;
			// true -> false, false -> true 
    }
    return data;
		// completed가 업데이트된 데이터
  });
  this.setState({todoData:newToDoData});
};

이렇게 기본적인 ToDo 앱을 만들었고 추가적인 기능을 통해 앱을 최적화할 예정이다

반응형

'WEB FE > React' 카테고리의 다른 글

[React] Component, State와 Props  (0) 2023.02.03
[React] React Hooks  (0) 2023.02.03
[React] Component LifeCycle Method  (0) 2023.02.02
[React] React 익히기: CRA, SPA, JSX  (0) 2023.01.28
[React] React란? 리액트의 개념과 설치  (0) 2023.01.27
Comments