✏️ 노션 프로젝트 회고

박민우·2023년 8월 3일
1

✏️ 회고록

목록 보기
4/8
post-thumbnail

23.06.27 ~ 23.07.06 동안 진행한 노션 클로닝 프로젝트를 회고해보고자 한다 !


📌 프로젝트 설계

프로젝트 기본 기능 및 요구사항

해당 프로젝트는 VanillaJS를 사용하여 노션 페이지를 클로닝하는 프로젝트로, 기본 요구사항은 다음과 같다.

  • 글 단위를 Document로, 각 Document는 여러 개의 Document를 포함할 수 있다.

  • 페이지 좌측에서 글의 목록을 트리형태로 보여주고, 우측에서 글의 제목과 내용을 보여준다.

  • 글의 제목과 내용을 수정하면, 서버에 자동으로 저장되게 한다.

  • history API를 이용해 SPA 형태로 만든다.

    => 좌측에서 특정 글을 선택하면 우측에서 그 글의 content를 불러온다.


이전에 VanillaJS를 사용하여 간단한 To do List 페이지를 만들어본 경험을 바탕으로, 프로젝트 시작 전 꼭 먼저 생각해야 할 것들을 정리해보았다.

컴포넌트별 데이터와 기능 확실히 분리 => 컴포넌트 간 의존성 최소화

✅ 컴포넌트 간 공유되는 데이터 및 데이터 관리 메서드

이 2가지 사항을 구현 시작 전에 미리 충분히 고민하고 확실히 정해놓아야, 내가 내 코드를 이해하기 쉬워지고 특정 기능을 추가하려고 할 때에도 어떤 컴포넌트 부분을 건드려야 하는지도 명확해질 것이라 생각했다.


📌 컴포넌트 구조

평소 내가 사용해왔던 노션 페이지를 바탕으로 컴포넌트를 어떻게 나눠야 할지 고민해보았다.

노션 페이지의 기능

  • 좌측 사이드바에서는 글의 목록을 확인할 수 있고, 새로운 글을 생성하고, 삭제하고, 하위 문서를 추가할 수 있으며, 특정 글의 제목을 클릭하면
  • 우측 편집 화면에서는 글의 제목과 내용을 확인하고 수정할 수 있다.

이를 바탕으로 각 화면에서 사용되는 데이터들을 생각해보았고, 각 화면마다 필요한 데이터가 생각보다 명확하게 구분됐다.

  • 좌측 사이드바에서 사용되는 데이터 => 전체 글 목록

  • 우측 편집 화면에서 사용되는 데이터 => 특정 글의 제목과 내용


또한, 좌측 사이드바에서 새로운 글을 생성하거나 특정 글을 선택한다면

=> 우측 편집 화면에서 그 글에 대한 제목과 내용을 보여줘야 하기 때문에, 이 둘 사이를 선택된 글의 id로 연결할 수 있겠다고 생각했고

=> 이를 최상위 컴포넌트인 App에서 state로 관리해준다면 각 컴포넌트들의 상호작용을 App에서 관리할 수 있겠다고 생각했다.

따라서, 전체적인 컴포넌트 구조를 다음과 같이 설계했다.


전체 컴포넌트 구조

component-structure

  1. 최상위 컴포넌트인 App 컴포넌트

    • state : 선택된 글의 id인 selectedDocumentId
    • render() : 전체 글 목록 documentList를 다시 불러와서 이를 SideBar 컴포넌트의 state로 전달해줌.
  2. 좌측 사이드바에 해당하는 SideBar 컴포넌트

    • state : 전체 글 목록인 documentList

    • 하위 컴포넌트인 DocumentList 컴포넌트

      • state : SideBar에서 전달받은 documentList
      • render() : documentList에 따라 전체 글 목록을 그려줌
  3. 우측 편집화면에 해당하는 EditPage 컴포넌트

    • state : 선택된 글의 id인 selectedDocumentId
    • render() : App의 selectedDocumentId가 변경될 때마다 state가 변경되고 그 때 마다 해당 글의 제목과 내용을 불러옴

컴포넌트를 크게 App, SideBar, EditPage 이렇게 3 부분으로 나눴고, SideBar 안의 document 목록에는 포함되는 요소들이 많다고 판단해, SideBar 하위에 DocumentList 컴포넌트도 만들어주었다.


컴포넌트 흐름

다음과 같은 흐름으로 컴포넌트들을 연결하려고 노력했다(실제로 이와 동일하게 구현하지는 못한 것 같다)

App에서 전체 state를 관리

=> 특정 컴포넌트의 이벤트 등을 통해 App의 state가 변경되면

=> 이에 따라 하위 컴포넌트들의 state 변경

=> state 변경됐으니 render를 통해 각 컴포넌트 화면 다시 그려주기


좀 더 구체적으로 노션 페이지의 전체적인 흐름을 상상해보면,

  • SideBar에서 전체 글의 목록을 확인하고 새로운 글을 생성하고 삭제할 수 있다.

  • 선택된 글의 제목과 내용을 EditPage에서 확인할 수 있다.

  • SideBar에서 특정 글이 선택된다면 => App 컴포넌트에서 selectedDocumentId를 설정해주고 => EditPage에서 이에 따라 글의 제목과 내용을 보여줌.

=> 결국 컴포넌트 간의 상호작용을 App에서 관리하기 때문에, 공통된 data와 이 data를 다루는 메서드들은 App 내에 정의하고, 이러한 data과 메서드들을 다른 컴포넌트 생성 시 인자와 콜백함수로 전달해주었다.


📌 핵심 기능 구현 과정

노션 프로젝트를 진행하면서, 프론트 개발에 있어서 중요하고 앞으로 자주 구현하게 될만한 기능들을 구현해볼 수 있었다.

이렇게 특정 기능을 구현한 과정을 좀 더 자세히 정리해 나중에 비슷한 기능을 구현할 때 도움이 되도록 만들 생각이다.

💡 이벤트 버블링을 이용한 이벤트 위임

💡 history API를 이용해 SPA를 구현하기

💡 디바운스를 이용한 자동 저장 기능


📌 완성본 및 느낀 점

구조 설계에 많은 시간을 투자하자

프로젝트를 시작할 때, 컴포넌트 구조 설계를 고민하는 데에 많은 시간을 투자할 수록 개발 진행이 더 수월해지는 것을 느꼈다. 각 컴포넌트마다 가지고 있는 data와 할 일을 명확하게 정하고, 나누자. 그리고 컴포넌트 간 공유되는 데이터와 그 데이터를 어떻게 조작할 지도 생각하자.


컴포넌트 별 공통 data 및 메서드의 역할을 확실히 정하자

각 컴포넌트 별로 공통적으로 state, setState(), render(), init() 등의 메서드를 정의할 때, 이 data와 메서드들의 역할을 일관성있게 정하는 것이 중요하다고 느꼈다. 컴포넌트 별로 각 메서드가 어떤 역할을 할지 정하는 것도 중요하지만, 컴포넌트들에 공통적으로 정의되는 메서드라면 다른 컴포넌트에서도 동일한 결의 역할을 해야 헷갈릴 여지가 없겠다고 생각했다.

특정 컴포넌트에서는 setState()가 state의 변경과 화면을 다시 그려주는 역할까지 담당하는데 다른 컴포넌트에서는 오직 state의 변경만 담당한다면, 통일된 구조가 없어 계속 헷갈릴 것이고, 이는 프로젝트의 볼륨이 커질수록 더 큰 문제가 될 것이다.


앞으로도 꾸준히 !

데브코스를 시작한 후 첫 프로젝트여서 그런지, 잘하고 싶은 마음이 컸고 그만큼 완성도 있게 만들고 싶어서 열심히 고민하고 또 노력했던 것 같다. 그래서 나에게는 애착이 많이 가는 프로젝트다.

노션 프로젝트를 진행하면서, "노션이라는 서비스가 가지고 있는, 또 가질 수 있는 기능이 굉장히 많을 수 있겠다"고 생각했고 이대로 프로젝트를 끝내는 것이 아니라, 내가 앞으로 학습하는 새로운 내용과 기술들을 이 프로젝트에 적용해보면서, 실제 노션 서비스와 비슷하게 또는 나만의 방식대로 발전시켜 나간다면 훌륭한 개인 프로젝트이자 나만의 개발 연습장이 되지 않을까 생각했다. 앞으로 이 프로젝트를 계속 다듬고, 발전시켜봐야겠다.

profile
꾸준히, 깊게

1개의 댓글

comment-user-thumbnail
2023년 8월 3일

정리가 잘 된 글이네요. 도움이 됐습니다.

답글 달기