본문 바로가기
회고록

[회고록] 리액트 토이프로젝트:생일 캘린더 (1차 작업)

by 경험을 기록하다. 2024. 3. 27.

📃 개요

리액트 강의에서 useState( ) 끝마친 후 학습한 내용을 활용하여 생일 캘린더를 구현했습니다.

⏳ 개발 기간

하루 3~5시간 소요

💻 프로젝트에서 활용한 기술 및 핵심 내용

  • HTML
  • CSS
    • CSS 파일 생성하여 스타일 적용
  • JavaScript
  • React
    • useState( ) 상태 관리 및 활용, 부모 컴포넌트로 끌어올리기
    • children, ...props 이용하여 컴포넌트 생성
    • Router 이용하여 페이지 이동
  • 캘린더 라이브러리 사용하지 않고 구현
    • new Date( )

🔥 구현한 기능

  • 생일 추가 (완료)
  • 생일 목록 (완료)
  • 캘린더 (완료)

✍ 회고록

일기장처럼 회고록을 작성했습니다.

🙂 진행 전

진행 전에 두려웠던 것은 "처음부터 내가 배웠던 대로 할 수 있을까?"였다. 리액트에서 useState( ) 훅만 배운 상태이며 JavaScript에 대한 많이 알지 않았기에 걱정이 됐고 어떤 구조로 만들어야 할 지, 로직에 대한 자신감이 없어서 어떻게 만들어야 할 지 감이 오지 않았기 때문에 시작하는 것조차 막막했다. 온라인 강의로 useState( ) 상태 관리 그 외 것들을 토이프로젝트에서 최대한 활용하고자 노력했다.

😭 진행하면서 어려웠던 점 및 고민한 부분

#1. 라이브러리 활용하지 않고 캘린더 구현

# 작업하기 전

캘린더 만들기 전 라이브러리가 있는지 검색했다. npm install react-calendar 있어서 라이브러리 활용할까? 아니면 직접 구현해서 처음부터 만들까? 고민했다.

 

# 문제

고민하면서 검색해 보았다. 라이브러리 활용하면 CSS 커스터마이징에 제약사항이 존재하여서 자유도가 낮았다. 활용하지 않고 구현하기로 했다.

 

# 작업 과정

자바스크립트에서 new Date( ) 활용했다. 알고 있는 메서드이고 익숙하였지만 UI 구현은 처음이었다. 어떻게 작업 할 지 로직을 그리면서 생각했고 구글링하여 남들이 구현한 코드가 있는지 살펴봤다. 또한 ChatGPT에게 물어보면서 참고하여 구현하였다. 캘린더 구현하는 핵심은 월의 첫 번째 요일, 날짜랑 마지막 요일, 날짜를 가져와서 활용하는 것이었다.

 

# 해결

new Date( ) 활용하여 캘린더를 구현하면서 캘린더 컴포넌트를 내꺼로 만들었다.

 

 

#2. 사용자 입장으로 디자인(UX/UI) 고민

# 문제

디자인 파일이 없는 상황에서 작업하니까 어떤 레이아웃으로 할까? 고민했다.

 

# 작업 과정

핀터레스트에서 디자인을 참고하여 피그마로 작업했다.

 

# 해결

심플한 디자인으로 작업했다. 그리고 UX/UI 이론을 알았다. 디자이너와 함께 UX/UI 개선 할 수 있을 것 같았다.

 

 

#3. 생일 날짜 값을 어떻게 받아와서 어떻게 뿌려줘야 하는지 고민하면서 어려웠다.

# 작업하기 전

input 값을 Ref로 받아오는 방법이 있고 onChange로 받아오는 방법이 있어서 Ref 다음에 사용해 보고 onChange로 작업하였다.

# 문제

input에서 onChange 이벤트를 사용하여 객체를 받아왔는데 useState([ ]) 상위 컴포넌트로 상태를 끌어올려서 화면에 데이터를 출력하려고 하였는데 초기에 설계를 잘못하였다.

# 해결하는 과정

코드 구조 변경하기에는 많은 시간이 지연될 것 같아서 현재 컴포넌트 구조에서 고민하다가 자바스크립트로 전역 상태를 관리하였다.

# 해결

자바스크립트 파일 생성하여 전역 상태를 관리하였다.

 

#4. 이전 달 마지막 주, 다음 달 첫째 주 스타일 제어하는 과정

# 작업하기 전

캘린더가 구현된 상태에서 추가로 작업하기 위해 로직을 다시 확인하였다.

# 문제

처음에는 이전 달 마지막 주, 다음 달 첫째 주 값을 가지고 와서 렌더링했지만 마지막에 렌더링한 컴포넌트가 화면에 출력이 됐다. 여기서 문제가 생겼다. 내가 생각한 로직대로 했지만 중복되고, 덮어쓰기처럼 렌더링이 나왔다.

# 해결하는 과정

로직이 잘못됐다는 것을 알고 곰곰이 생각했다. 마침내 10~20까지 숫자만 골라서 화면에 출력할 수 있는 로직이 생각나서 map( )에서 for 문으로 현재 달의 날짜를 가져와서 if 문으로 1일~31일까지 출력하고 이전 달 마지막 주, 다음 달 첫째 주를 for 문밖에다가 출력했다.

# 해결

 

#5. 캘린더에서 해당하는 날짜를 클릭하면 그날의 생일자 출력

# 문제

해당하는 날짜를 클릭하니 오늘 날짜만 출력이 됐다. 원인을 찾기 위해 개발자 모드에서 console.log( )로 확인하면서 원인을 찾았다. 코드에서 오늘 날짜만 클릭하도록 코드가 되어있었다.

# 해결하는 과정

자바스크립트 코드 e.target.innerText로 클릭하면 해당하는 날짜를 반환하여 filter( ) 메서드로 이용하여 해결하였다.

https://hianna.tistory.com/406

 

[Javascript] 배열의 특정 값 찾기 - find(), filter()

배열에서 특정 값을 찾는 방법을 알아보고 있습니다. 앞에서는 특정 값이 배열에 존재하는지, 존재한다면 어느 위치에 있는지 찾는 방법을 알아보았습니다. [Javascript] 배열 특정 값 위치(index) 찾

hianna.tistory.com

# 해결

이를 해결함으로써 filter( ), find( ) 메서드를 알았다.

 

#6. 캘린더 페이지로 이동하면 오늘 날짜로 표기

# 작업하기 전

1일~마지막 날짜에서 CSS만 추가만 하면 되는 줄 알았다.

# 문제

캘린더 페이지로 이동하면 오늘 날짜로 표기하는 로직을 구해야 한다.

# 해결하는 과정

1일 ~ 마지막 날짜의 배열에서 if (현재 날짜 === index) { ... } 하였지만 오늘 날짜가 표기가 되지 않았다. 여기서 어떻게 해야 할 지 생각을 하였다. 내가 생각한 것들은 1일 ~ 마지막 날짜의 배열에서 오늘 날짜를 구현하거나, index에서 월의 첫째 주 없는 날짜를 시작하는 날짜에서 오늘 날짜까지 계산하여 구현하였고 생각대로 되지 않아서 개발을 잠시 멈추고 어떻게 구현할지 또는 규칙을 찾기 위해 생각하였다.

# 해결

현재 월의 시작하는 요일 + 오늘 날짜 - 1로 계산한 값이 10이 나오고 index는 현재 월의 들어가는 index이자 35개다. 그러면 0부터 시작하여 오늘 날짜가 나온다. (이미지 참고)

포토샵으로 만들었으며, index 표현하였다.
오늘 날짜 조건문 구하기

 

#7. 지역 상태로 관리하고 있어서 형제 컴포넌트에 전달 못 하는 상황

# 작업하기 전

부모 컴포넌트에서 useState( ) 선언하고 setState( ) 활용하여서 전달하면 되는 줄 알았다.

# 문제

날짜 데이터를 지역 상태에서 관리하였다. 그러다 보니 다른 컴포넌트에 props 전달하지 못하였다. 부모 컴포넌트 말고 자식 컴포넌트에다가 상태를 관리하다 보니까 이러한 상황이 발생하였다.

# 해결하는 과정

이를 해결하기 위해 부모 컴포넌트에서 상태를 관리하기 위해 코드를 리팩토링하였다.

 

(물론 컨텍스트API, 리덕스, 리덕스 툴킷을 사용하여 전역 상태로 관리하면 되지만 현재 프로젝트는 사용하지 않고 공부 목적 및 useState( ) 활용하여 포트폴리오 목적이어서 사용하지 않았다. 다음에 더 배우면 추가 작업할 계획이다.)

# 해결

부모 컴포넌트에서 상태 관리하여 자식 컴포넌트에 props 전달하였다. 깃허브에 코드를 커밋한 내역이 있어서 URL로 갈음한다.

https://github.com/wangkodok/birthday-webapp/commit/15ada6343e8de3f1cecadf0cbae2d255fe771bf7

 

부모 컴포넌트에서 날짜 상태 관리 · wangkodok/birthday-webapp@15ada63

wangkodok committed Feb 15, 2024

github.com

 

#8. 생일 추가 페이지에서 프로필 이미지 업로드

# 문제 발생하기 전

작업하다가 놓쳤던 부분이 발생했다. 프로필 사진 업로드 UI에서 img 태그나 백그라운드 이미지로 작업하는 줄 알고 백그라운드 이미지로 스타일 작업했다. (아래의 이미지 참고)

# 문제

프로필 이미지를 올리는 UI인데 img 태그나 백그라운드로 작업하고 onClick으로 이미지 경로를 변경하는 줄 알았고 HTTP 통신이 되지 않도록 form 태그 감싸지 않고 작업하였다.

# 해결하는 과정

HTTP 통신하여 데이터를 서버에 저장하기 위해서는 form 태그로 감싸서 작업한다. 사진 올리면 카카오톡 프로필 변경하는 것처럼 UI를 만들고 싶어서 이미지 파일을 어떻게 올리는지 찾아보며 구현하였다. 이 경험으로 인사이트를 얻었다.

# 참고하여 해결한 글

새로운 것을 알아가면서 성장하였다.

https://hayley-0616.tistory.com/57

 

[React] input 으로 프로필 이미지 업로드 하기

👀 컴퓨터 안에있는 파일 이미지를 이용해서 업로드 할 수 있는 기능을 구현해 보았다! 생각보다 간단해서 정리해 보았다 :) 이용한 것 - input type: file - useState import React, { useState } from 'react'; impor

hayley-0616.tistory.com

 

#9. 프로필 이미지를 추가하고 목록에 프로필 이미지 화면에 구현

# 작업하기 전

생각한대로 로직을 구현하였는데 프로필 이미지가 나오지 않았다. 그래서 "왜? 프로필 이미지 안 나오지?" 생각하였고 내가 구현한 코드를 분석하였다.

# 문제

생일 목록에서 프로필 이미지가 나오도록 구현하였는데 화면에 나오지 않아서 "왜? 프로필 이미지가 안 나오지?" 생각하고 코드를 분석하였다. 프로필을 받아오지 못하고 input에서 데이터 Blob 값을 받아왔는데 할당되지 않아서 문제가 발생하였다.

 

1. useState( )에서 profile 객체를 추가하지 않아서 문제가 됐다.

 

2. 데이터 Blob 값을 받아왔는데 다른 경로로 profile에 할당되지 않아서 문제가 됐다.

 

# 해결하는 과정

내가 생각한 로직으로 이것저것 코드 삽질(?) 시도하였지만 Blob 값을 profile에 할당되지 않았다. 구글링하고 한참을 찾다가 URL.createObjectURL( ) 메서드를 알고 적용하였더니 할당이 되었다.

# 해결

URL.createObjectURL( ) 메서드를 사용하여 해결하였다. 이 과정에서 서버로 이미지를 보낼 때 input에서 type="file" 속성을 활용하였고 이미지는 URL.createObjectURL( ) 메서드 이용하여 보내는 것을 배웠다. 삽질(?)을 경험하고 새로운 것을 알아가면서 성장하였다.

 

#10. 생일 추가하고 캘린더 페이지에서 오늘 날짜의 목록이 나오지 않았다.

# 작업하기 전

캘린더 페이지로 이동하면 오늘 생일자의 목록이 나올지 우선 생각하고 작업하였다.

# 문제

캘린더 페이지로 이동하면 오늘 날짜가 출력되어야 하는데 출력이 되지 않아서 원인을 찾기 위해 캘린더 페이지로 이동하면서 console.log( ) 출력하면서 확인하였다. 그러더니 빈 객체가 있었다.

# 해결하는 과정

자식 컴포넌트에서 객체를 활용하고 있었던 것이다. 이를 해결하기 위해 부모 컴포넌트로 상태를 끌어올려서 해결하고 useState( ) 초기 값으로 오늘 날짜를 설정하고 클릭하면 상태를 변경하는 로직으로 변경하여 해결하였다.

# 해결

(해결한 UI 영상)

😊 진행하면서 놓치거나 아쉬웠던 부분

# 1.

자식 컴포넌트에서 상태 관리하니까 다른 자식 컴포넌트로 props 값을 보낼 때 문제가 되어서 코드 고치는데 시간 소요가 됐다. 다음에는 상태 관리를 부모 컴포넌트에서 관리하고 자식 컴포넌트에서 상태 관리해도 상관 없는 useState( ) 있으면 자식 컴포넌트로 관리해야 하겠다.

# 2.

기획, 디자인 없이 작업하니까 어떤 기능들이 들어갈 지 생각하고 개발에 들어가니까 작업 기간이 조금 소요됐다. 실무에서 기간도 중요해서 작업 속도가 아쉬웠다. 다음 프로젝트에서는 최소한 기획, 디자인을 작업하고 개발 속도를 올리고 개선해야 하겠다.

# 3.

전체 코드에서 중복된 코드가 있고 불필요한 코드가 있어서 아쉬웠다. 공부 더 하고 리팩토링 생각하고 있다.

# 4.

useState( ) 연습하는 목적으로 하다보니까 기능이나 다른 훅들이 더 필요해 보였다. 다른 훅들 공부 더 하고 이름, 생일 날짜를 수정하는 것도 구현해야 하겠다.

# 5.

children, ...props 활용하여 재사용이 가능한 컴포넌트를 생성하면 좋았을텐데 활용하지 못하여서 아쉬웠다.

# 6.

다음 챕터로 넘어가서 공부하고 이 프로젝트를 보니까 상태 관리가 많이 아쉬웠다.

# 7.

대략적으로 만들고 나서야 추가로 들어가야 하는 기능들이 보였다. 기획+디자인 하지 않고 개발에 들어가서 아쉬웠다.

📈 진행 후 성장과 배운 점

1. 부모 컴포넌트로 useState( ) 끌어올려서 자식 컴포넌트에게 값 전달

2. useState( ) 상태 관리 및 함수형 업데이트로 작성

3. 라이브러리 없이 캘린더 만들었던 경험 및 인사이트

4. children, ...props 활용하여 재사용 가능한 컴포넌트 생성

5. HTTP 통신하기 위해 사용하는 from tag 활용하여 구현

6. 자바스크립트 기본을 더 학습하라는 메시지를 얻어서 학습 진행 중

7. 작업하기 전 어떻게 구현할지 로직을 생각하고 개발하기

 

이외 많은 성장과 배움이 있었습니다. 이전에 몰랐던 children, ...props / HTTP 통신 / useState( ) 함수형 업데이트 ··· 등 있었는데 이 경험을 통해 알았고 한 걸음 더 성장한 모습이었습니다.

📚 더 공부해야 할 것

#1. 익숙해지기 위해서 반복 학습

막히거나, 공부한 기억이 나지 않을 때 배웠던 코드를 참고하는 용도로 봤다. 다음에는 안 보고 프로젝트를 할 수 있도록 반복 학습하면서 조금씩 기술 면접을 대비해야겠다.

 

#2. 어려운 기능이나 새로운 기능을 구현하면서 역량을 강화

그동안 해보지 않았던 기능을 구현해보고 다른 코드로도 접해보면서 역량을 강화하고 인사이트를 얻어야 하겠다.

 

#3. UI 분석하고 작업 시작

캘린더 목록처럼 다른 페이지에서도 사용하는 상태 관리이면 최상위 컴포넌트에서 관리해야 되는데 나는 자식 컴포넌트에서 상태 관리하다가 props 값을 전달하지 못한 상황이 발생하였다. 이러한 시행착오로 UI 분석하고 개발을 시작하고 프로젝트 설계 관련하여 공부해야 하겠다.

 

#4. 깊게 생각하는 습관 (Feat. 생각하는 훈련)

어떻게 해야 구현할 수 있을까? 생각하는 훈련이 되지 않아서 시간이 걸렸던 것 같다. 이를 해결하기 위해 생각하는 습관을 기르고 범위를 넓혀가야겠다.

 

#5. 메서드, 프로퍼티 많이 알고 있어야 하겠다.

기능 구현할 때 어떤 메서드, 프로퍼티를 사용해야 할까? 생각하고 구글링으로 찾아서 구현하였다. 많은 것을 알기 위해 다양한 기능 구현을 하면서 사용하지 않았던 위주로 사용해야 하겠다.

 

👋 끝

부족한 저의 글솜씨였지만 끝까지 읽어주셔서 고맙습니다. (고개 숙여 인사 꾸벅)