티스토리 뷰

활동/Dev Course 회고

Notion 개발 회고(VanillaJS) + JS 구조

geonwoopaeng@gmail.com 2022. 4. 19. 16:47

Notion 제작 및 문제해결!!

프로젝트를 한 순서대로 글을 작성하는데 자잘한 문제보다는 큰 문제 위주로 회고를 작성한 것 입니다.

편하게 읽어주세요 :) 처음 들어가기 앞서 실행 영상을 보고 가도록 하겠습니다. !!!

 

주위에서 처음에 밤을 새워야 한다라고 겁을 너무 많이 주셔서 겁을 많이 먹었던 것 같아서 내가 할 수 있을 까?? 라는 의문점을 가지고 시작을 했습니다.

 

📦public
 ┣ 📂api
 ┃ ┗ 📜kdt-api.js
 ┣ 📂components
 ┃ ┣ 📜app.js
 ┃ ┣ 📜editor.js
 ┃ ┣ 📜linkButton.js
 ┃ ┣ 📜postEditPage.js
 ┃ ┣ 📜postList.js
 ┃ ┣ 📜postPage.js
 ┃ ┗ 📜postRootList.js
 ┣ 📂constants
 ┃ ┣ 📜constants.js
 ┃ ┗ 📜dummy.js
 ┣ 📂css
 ┃ ┣ 📜reset.css
 ┃ ┗ 📜style.css
 ┣ 📂utils
 ┃ ┣ 📜buttonClickEvent.js
 ┃ ┣ 📜buttonHover.js
 ┃ ┣ 📜editDbPost.js
 ┃ ┣ 📜insertnonePost.js
 ┃ ┣ 📜returnHTML.js
 ┃ ┗ 📜router.js
 ┣ 📜index.html
 ┗ 📜main.js

와 엄청 많다.... ㅋㅋㅋㅋㅋ 간단한 구조는 다음과 같습니다.

이젠 시작합니다. !!!

 

1. 큰 구조(Component) 짜기 !!

app을 가장 큰 틀로 postPageEditPage를 만들었으며
postPage에는 Api에서들어온 데이터들을 Nesting List가 있는 Page 입니다.
EditPage에는 editor 부분이 있는 Page 입니다.

이것을 바탕으로 빠르게 제작을 시작했습니다.
빨리 안하면 완성 못 할 것 같아 ....

 

2. Api 데이터 형태에 맞는 LIst 제작...

다음과 같이 데이터가 생겼으며 documents 안에 다음과 같은 형태의 데이터가 계속 들어있습니다.

  [
    {
      "id": 1,
      "title": "hello1",
      "documents": []
    },
    {
      "id": 2,
      "title": "hello2",
      "documents": []
    },
    ...
  ]

여기서 벌써 문제가 생겼습니다 !!

> 문제: List를 어떤 식으로 그릴 것 인가! + event

다음과 같이 그려야 합니다.

여기서 방법을 2가지 정도 생각을 했습니다.

1. 전체를 그리고 난 후 "hidden" 으로 숨긴 다음 event를 통해 보이게 실행한다.

2. Root 부분이 되는 것을 그리고 난 후 event가 실행이 되면 끼워 넣는 식으로 한다.

처음에는 1번으로 재귀를 이용해서 제작을 했습니다... 그런데!!!!
데이터가 얼마나 들어올지도 모르는데 다 그려놓고 있으면 굉장히 비효율 적인 것 같았습니다.
아직 이정도 생각할 정도는 아니지만...

또한 나중에 계속 rendering을 해주는 귀찮음이 있을 것 같아서 2번을 선택하게 되었습니다.

아주 좋은 선택이었습니다. ㅎㅎㅎ

그래서 2번으로 RootList를 제작하고 추가된 List를 추가하는 함수를 제작했습니다.

+ 비하인드 스토리...

List 부분을 표현하는데 끼어 넣는 식으로 한 후에 그렸던 것을 지우지 않고 hidden attribute를 사용하여 하다가 너무 코드가 드러워서 다시 완전 삭제 후 끼워 넣는 식으로 방법을 돌아왔다는 뺑뺑 돈 썰..

3. Dummy Data -> API Data

그냥 만든 Dummy Data에서 Api Data를 설정하여야 했고
Api Data를 건드는 일이 쉽지 않은 저는 도구의 힘을 빌렸습니다. ㅎㅎㅎㅎ

https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

 

Advanced REST client

The web developers helper program to create and test custom HTTP requests.

chrome.google.com

 

여기서 부터는 강의 내용을 바탕으로 editor 부터 시작해서 쭉쭉 제작을 이어나갔습니다.

그런데 이것이 문제였습니다.

4. 갈아 엎기...

강의에 있는 코드 토대로 계획 없이 주먹구구식으로 추가 제작을 하다보니 components 간의 state 동작이 꼬이고 꼬이고 있었습니다.

- Click 부분(list button, post, 추가 button, 삭제 button) 이 있었는데 각자의 많은 조건 추가
- Click 후 수정을 하게 된 후 깜빡임을 없애기 위해 DB저장 전에 미리 있는 것처럼 해주는 낙관적 방법을 추가
- Test 하면서 문제 발생시 하나씩 하나씩 조건 추가

하다 보니 내 코드를 보기 싫을 정도까지 오게 되었습니다.
그래서 강사님의 코드를 완벽한 이해도 없이 이용한 죄 라고 생각을 하고 죄 값 치르는 겸 새로 생각을 하게 되었습니다.


아무리 잘하는 분의 코드라도 완벽하게 이해를 하고 추가를 하던가 해야 겠다는 깨달음을 얻었습니다.

우선 Components까지 짜는 것은 괜찮았습니다. 이 후 아무 생각 없이 개발 한 것이 문제였지...
구조를 짜는 것부터 문제다 라는 결론에 도달했고 다시 생각을 하게 되었습니다.

> 문제: notion을 개발하는데 중요한 것은?

이 생각을 가지고 다시 생각을 해보니 해야하는 요구사항큰 기능 들이 눈에 보이고 조건을 하나씩 추가하는 부분에서 부터 코드가 드러워지는 것을 알게 되었습니다.

큰 기능

- Click Event(list button, post, 추가 button, 삭제 button) 4가지
- components로 나눠서 수행
- SPA기능

으로 나누었습니다.

> Components로 나누어 수행 + JS 구조

은 위의 그림과 같이 나눴고

export default function a({$target, init}){

  this.state = init; //사용할 데이터

  this.setState = (nextState) => {
    //다른 Componenet에서 update 된 내용 update
    this.state = nextState;
    this.render(); 
  }

  this.render = () => {} //수행 부분
}

같은 형태로 생각을 하면 됩니다.

> SPA 기능

router.js라는 파일과 이동하는 부분과 각Component 별로 이동을 하게 만들어서 완료를 해놨습니다.

내 블로그을 보던가 다른 분들의 블로그를 보던가.

> Click Event(list button, post, 추가 button, 삭제 button) 4가지

postPage, editPage부분을 고려해서 조건을 생각하게 되었고 하나씩 제작을 완료하고 다른 것을 건들이자!! 라는 생각으로 하였습니다.

이와 같이 조건을 작성을 하고 이것은 노트에 쓴 것을 간략화 한 것 입니다. ㅋㅋㅋㅋ
이렇게 조건에 맞춰서 하나씩 하던 중

> 문제: +버튼을 눌렀을 때 해당 id를 어떻게 전달하나

라는 문제를 파악하게 되었습니다. Parent Id가 있어야 DB에도 정상적으로 값을 넣고 수정을 원활하게 할 수 있었습니다.

그래서 + 버튼 통해 새로운 것을 추가하면 approute를 통해 https://.../new라는 page로 이동을 합니다.

 

해당 값은 다음을 통해 얻습니다.

this.route = async () => {
  const { pathname } = window.location;
  const [, , postId] = pathname.split("/");
  //postId 가 new or 다른 ID
}


여기서 new가 중요하게 작용을 했습니다. new를 통해 새 editPageparent Id를 전달하는 방식으로 문제를 해결하였습니다.

 

다음 문제를 해결하니 깜빡이는 문제를 해결하려고 했습니다.

> 문제: 깜빡이 문제

이 부분은 DB Data가 업데이트가 될 때마다 데이터를 받아 다시 처음부터 rendering을 해줘서 생긴 문제였습니다.
그래서 낙관적 방법으로 전체 rendering 되는 것을 방지했고

this.render = () => {
 $target.appendChild($postPage); 
}

this.init = async () => {
 cosnt post = await request(``);
 postRootList.setState(post);
 this.render();
}

위의 2개의 함수를 만들어서 처음에 `this.init()`으로 초기화를 한 후 `this.render()`를 이용해서 그려져 있는 것을 붙이기만 하는 것으로 문제를 해결하였습니다.

 

드디어

큰 문제들은 여기까지 해서 기능 구현을 마무리 하였습니다.

.......

이젠 CSS 한다..... 이게 더 문제다.....

BootStrap을 사용하려 했는데 처음부터 라이브러리는 좀.... 아닌 것 같아서 기본적인 것을 탄탄히 하기 위해 기본 CSS로 제작을 하게 되었는데 CSS를 하며 가장 잘 느낀 것은

*BOX 구조 잘쓰자*

입니다. 어떻게 보면 box 형태 안의 box 그 안의 box를 grid, flex등으로 구조를 조작하고 꾸미면 되는 것이라고 느꼈고 상하차를 했어서 그런지 box 형태를 잘 파악해서 생각보다 쉽게 되었는데...?

> 문제: hover 문제

마우스를 올려 놨을 때 해당 부분의 +, x 버튼과 색이 변하는 것을 만들고 있었습니다. 그래서 Css에서 제공하는

선택자:hover {}

을 사용하였는데 부모까지 bubbling 되는 문제가 발생하였습니다.
StackOverflow에서 많은 글을 읽었지만 왠만해서는 좋지 못한 코드가 나오니 하지 말라 했는데 괜히 고집이 생겨서  StackOverflow 이 글을 보고 pointer-events를 수시로 설정해주는 것을 했는데 실패했습니다. ㅋㅋㅋㅋㅋㅋ 할 수 있었는 데... 까비

결국 addEventListener의 옵션 중 mouseover, mouseout 기능을 사용하여 문제를 해결하였지만 마음에 안든다...

//button hover
export const buttonHover = ($target) => {
  $target.querySelectorAll("li").forEach((post) => {
    post.addEventListener("mouseover", (e) => {
      const $targetLi = e.target.closest("li");
      $targetLi.querySelector("button").style.backgroundColor = "#D6D2C8";
      $targetLi.querySelector("span").style.backgroundColor = "#D6D2C8";
      $targetLi.querySelector("div").style.display = "inline";
    });
    post.addEventListener("mouseout", (e) => {
      const $targetLi = e.target.closest("li");
      $targetLi.querySelector("button").style.backgroundColor = "#E2DFD6";
      $targetLi.querySelector("span").style.backgroundColor = "#E2DFD6";
      $targetLi.querySelector("div").style.display = "none";
    });
  });
};

 

그래도 문제를 해결하여 다음과 같은 결과를 얻게 되었습니다.

 

 

마치며

후기를 처음으로 꼼꼼히 작성하였습니다. 뭔가 잘 못 썼지만 다시 전체적으로 다시 복습하는 기분과 문제 해결 부분을 작성하니 기억에 많이 남을 것 같습니다. 결국 까먹긴 하겠지만
많은 문제를 겪다보니 많은 성장?을 한 것 같은 기분이 들고 개발을 할 때 단순 구현 -> 정리 -> 특정 기능 구현 -> 정리 -> 특정 기능 구현 -> 정리 ... 와 같이 해야 잘 구현이 될 것이라는 점과 다른 이의 코드를 사용할 때는 확실한 이해를 바탕으로 사용을 해야 겠습니다. 결국 스스로 만든 것이 좋지만 혹시 모르니까 :) 자잘자잘한 문제들도 잘 정리하면 좋았을 껄이라는 아쉬움이 듭니다. 이젠 중간 벌레정도로 진화한 듯 ㅎㅎㅎ

프론트를 잘 선택했다

반응형

'활동 > Dev Course 회고' 카테고리의 다른 글

Code Review 회고(1~7)  (0) 2022.05.23
영화 검색 회고 (w. Vue)  (0) 2022.05.19
Airbnb 회고(SCSS)  (0) 2022.05.05
고양이 사진첩(Vanilla JS) 회고  (0) 2022.04.26
프로그래머스 데브 코스 합격? 불합격? 후기  (2) 2022.03.09
공지사항
최근에 올라온 글