본문 바로가기
TIL/디지털트윈

06.07 디지털 트윈 부트캠프 37일차

by saramnim 2023. 6. 7.
728x90
프론트엔드 - React

Todo List 만들기

1. 초기 구현

import React, { useState } from "react";

export default function Todo() {
  const [todos, setTodos] = useState([]);
  return (
    <>
      <ul>
        {todos.map((item, index) => {
          return <li key={index}>{item}</li>;
        })}
      </ul>
    </>
  );
}

먼저, ul 태그 내에 여러 개의 li 태그가 늘어나는 형식으로 코드를 초기 구현한다.

map을 사용해 각 item의 값을 나타내며 key 값을 인덱스로 갖도록 했다.

 

다음으로 할 일을 입력 받아야 한다.

입력 받을 때는 주로 form과 input을 사용한다.

 

<form>
  <input type="text" placeholder="할 일을 쓰세요." name="todoText" />
  <input type="submit" value="추가" />
</form>

form  안에 두 개의 input 태그를 작성한다.

하나는 할 일을 입력 받은 text 타입의 input 태그, 다른 하나는 할 일을 추가할 submit 타입의 input 태그이다.

이 때, submit 버튼을 누르면 할 일이 추가되는 것이 아닌 리로드 되는 것을 확인할 수 있다.

이를 방지하기 위해,

 

2. 할 일 작성

<form
  onSubmit={(e) => {
    e.preventDefault();
    setTodos([
      ...todos, // 배열의 요소나 객체의 멤버를 그대로 복사, 쉼표는 최신화
      {
        todoText: e.target.todoText.value,
      },
    ]);
  }}
>
  <input type="text" placeholder="할 일을 쓰세요." name="todoText" />
  <input type="submit" value="추가" />
</form>

text 타입의 input 태그에 todoText라는 name 프로퍼티를 할당 해 준다.

그 다음 위와 같이 onSubmit 이벤트에 e.preventDefault를 추가한 후, setTodos에 내가 작성한 todos를 불러오고, todoText의 value 값을 지정해준다.

이러면 리로드가 방지되며 todo 작성 시 값이 남는 것을 확인할 수 있다.

todos의 상태가 바뀌면 바뀐 최종 값을 로컬 저장소에 저장

 

3. 할 일 삭제

const [todoId, setTodoIds] = useState(0);

컴포넌트 내에 useState를 하나 더 선언한다.

<form
  onSubmit={(e) => {
    e.preventDefault();
    console.log(e.target.todoText.value);
    setTodos([
      ...todos, // 배열의 요소나 객체의 멤버를 그대로 복사, 쉼표는 최신화
      {
        todoId: todoId,
        todoText: e.target.todoText.value,
      },
    ]);
    setTodoIds(todoId + 1);
  }}
>

추후 delete 기능을 위한 todoId라는 state를 추가해줬다.

 

const handleDelete = (deleteId) => {
  setTodos(
    todos.filter((item) => {
      return item.todoId !== deleteId;
    })
  );
};

내가 선택한 deleteId와 todoId가 같으면 필터링으로 그걸 제외한 모든 todo만 남게 하는 함수 handleDelete를 생성했다.

 

<ul>
  {todos.map((item, index) => {
    return (
      <li key={index}>
        <span>{item.todoText}</span>
        <span onClick={() => handleDelete(item.todoId)}> X </span>
      </li>
    );
  })}
</ul>

이를 span 태그의 onClick 이벤트에 위에서 생성한 함수 handleDelete를 넣어주면, 할 일 목록을 삭제하는 기능을 완성했다.

 

4. 할 일 완료

다음으로 토글 방식으로 할 일 목록을 완료하면 줄을 긋는 기능을 만들어보자.

const [todoDone, setTodoDone] = useState(false);

// 내가 킁익한 todo만 todoDone의 상태를 바꾼다.
const handleToggle = (toggleId) => {
  setTodos(
    todos.map((item) => {
      return item.todoId === toggleId
        ? { ...item, todoDone: !item.todoDone }
        : item;
    })
  );
};

할 일 상태를 나타내는 todoDone state를 선언한다.

또한 todoDone state를 변경할 함수 handleToggle을 생성했다.

할 일 목록을 삭제하는 것이 완료된 상태로 변경하는 함수로 이번엔 map을 사용해준다.

map을 사용해 할 일(item)의 해당 인덱스(todoId)의 상태(todoDone)를 true or false로 변경할 수 있도록 한다.

선택한 Id가 동일하면 todoDone이 변경되고 다르면 변경되지 않는다.

이때 처음에 false로 상태를 지정했으므로,  toggle 시 true, 또 한 번 toggle 시 false로 변경된다.

true = 완료, false = 미완료 인 것이다.

 

{
  todoId: todoId,
  todoText: e.target.todoText.value,
  todoDone: false,
},

마찬가지로 setTodos 안에 todoDone을 지정해준다.

 

<span
  style={{
    textDecoration: item.todoDone ? "line-through" : "none",
  }}
  onClick={() => handleToggle(item.todoId)}
>

할 일 목록을 담당하는 span 태그 안에 style을 지정해준다.

todoDone이 true이면 줄을 긋고, false이면 아무 선도 나타나지 않는다.

onClick 이벤트에 handleToggle 함수를 지정해 클릭 시 todoDone의 상태가 변하게 만든다.

 

배포(deploy)

웹 상에 파일, 이미지 등의 소스를 올려 공유하는 작업

1. react app build

 => 정적 문서 형태로 만든다.

2. web hosting service

 => netlify

 

최종적으로 완성한 사이트

https://saramnim-todo-from-github.netlify.app/

 

Your Todo

 

saramnim-todo-from-github.netlify.app


display

요소의 유형을 정의(block, inline) + 경우에 따라, 내부 레이아웃도 정의(flex)

 

HTML 요소의 유형

블록레벨 요소

인라인 요소

 

display: flex;

요소 자신은 블록 레벨 요소

그 자식 요소들은 flex item이 된다.

 

flex 컨테이너를 위해 존재하는 속성들

justify-content: 주축에서의 배치 방법을 결정

align-items: 교차축에서의 배치 방법을 결정한다.

flex-wrap: 자식 요소들이 두 줄 이상 배치될 수 있을지를 결정한다.

flex-direction: 주축과 교차축을 바꾸고 싶을 때 그 여부를 결정한다.

 


axios

nodejs와 브라우저를 위한 Promise 기반 HTTP 비동기 통신 라이브러리외부 모듈이며, 다음 명령어로 설치한다.

npm i axios

axios를 사용해 클라이언트 사이드에서 데이터를 주고받을 수 있다.

다른 장소(서버, 외부 PC)로부터 데이터를 가져와 내 페이지에 반영할 수 있다.

HTTP 비동기 데이터 통신

프로미스: 비동기로 데이터를 요청하는데, 잘 가져와지면 그때 추가 작업도 수행

promise를 반환한다.

 

import axios from 'axios'

위의 방법으로 axios를 불러오자.

 

get

axios.get("요청주소")
axios.get("요청주소", {
	params: {
    	매개변수명: 매개변수값
    }
})

get으로 데이터를 불러올 수 있다.

 

post

axios.post("요청주소", {
	매개변수명: 매개변수값,
    매개변수명: 매개변수값,
    ...
})

post로 데이터를 등록할 수 있다.

 

async-await

axios를 이용해 promise를 반환하는 함수를 만들 때는 async-await을 사용하기도 하는데, 이때 오류 디버깅을 위해 예외처리 구문을 추가한다.

async function getUser() {
  try{
    const response = await axios.get('요청주소');
    console.log(response);
  } catch (err) {
  	console.error(err);
  }
}

 

API(Application Programming Interface)

프로그래밍에 도움을 주는 라이브러리, 툴킷 등을 통틀어서 표현하는 용어

 

REST API

요청을 처리하여 데이터를 제공해주는 url 형태의 API

dog api를 검색하면 아래 사이트가 나오는데, 강아지들 사진을 무료로 얻을 수 있는 API이다.

https://dog.ceo/dog-api

 

<h1>pug, beagle, mix, akita 중 골라서 써보세요.</h1>
<input
  type="text"
  placeholder="견종"
  onChange={(e) => {
    setDogBreed(e.target.value);
  }}
/>
<input
  type="submit"
  onClick={async () => {
    try {
      const response = await axios.get(
        `https://dog.ceo/api/breed/${dogBreed}/images/random`
      );
      setDogImage(response.data.message);
    } catch (err) {
      console.log(err);
    }
  }}
/>
<br />
<img src={dogImage} alt="랜덤하게 얻어온 강아지 사진" />

위와 같이 작성하면 input에 4 견종 중 하나를 입력하면 해당 견종의 사진이 랜덤하게 출력된다.

 

728x90
반응형

댓글

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."