Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[10팀 김정은] [Chapter 1-1] 프레임워크 없이 SPA 만들기 #28

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

jungeun0712
Copy link

@jungeun0712 jungeun0712 commented Dec 18, 2024

과제 체크포인트

기본과제

1) 라우팅 구현:

  • History API를 사용하여 SPA 라우터 구현
    • '/' (홈 페이지)
    • '/login' (로그인 페이지)
    • '/profile' (프로필 페이지)
  • 각 라우트에 해당하는 컴포넌트 렌더링 함수 작성
  • 네비게이션 이벤트 처리 (링크 클릭 시 페이지 전환)
  • 주소가 변경되어도 새로고침이 발생하지 않아야 한다.

2) 사용자 관리 기능:

  • LocalStorage를 사용한 간단한 사용자 데이터 관리
    • 사용자 정보 저장 (이름, 간단한 소개)
    • 로그인 상태 관리 (로그인/로그아웃 토글)
  • 로그인 폼 구현
    • 사용자 이름 입력 및 검증
    • 로그인 버튼 클릭 시 LocalStorage에 사용자 정보 저장
  • 로그아웃 기능 구현
    • 로그아웃 버튼 클릭 시 LocalStorage에서 사용자 정보 제거

3) 프로필 페이지 구현:

  • 현재 로그인한 사용자의 정보 표시
    • 사용자 이름
    • 간단한 소개
  • 프로필 수정 기능
    • 사용자 소개 텍스트 수정 가능
    • 수정된 정보 LocalStorage에 저장

4) 컴포넌트 기반 구조 설계:

  • 재사용 가능한 컴포넌트 작성
    • Header 컴포넌트
    • Footer 컴포넌트
  • 페이지별 컴포넌트 작성
    • HomePage 컴포넌트
    • ProfilePage 컴포넌트
    • NotFoundPage 컴포넌트

5) 상태 관리 초기 구현:

  • 간단한 상태 관리 시스템 설계
    • 전역 상태 객체 생성 (예: 현재 로그인한 사용자 정보)
  • 상태 변경 함수 구현
    • 상태 업데이트 시 관련 컴포넌트 리렌더링

6) 이벤트 처리 및 DOM 조작:

  • 사용자 입력 처리 (로그인 폼, 프로필 수정 등)
  • 동적 컨텐츠 렌더링 (사용자 정보 표시, 페이지 전환 등)

7) 라우팅 예외 처리:

  • 잘못된 라우트 접근 시 404 페이지 표시

심화과제

1) 해시 라우터 구현

  • location.hash를 이용하여 SPA 라우터 구현
    • '/#/' (홈 페이지)
    • '/#/login' (로그인 페이지)
    • '/#/profile' (프로필 페이지)

2) 라우트 가드 구현

  • 로그인 상태에 따른 접근 제어
  • 비로그인 사용자의 특정 페이지 접근 시 로그인 페이지로 리다이렉션

3) 이벤트 위임

  • 이벤트 위임 방식으로 이벤트를 관리하고 있다.

과제 셀프회고

javascript로만 코드를 작성해 본 경험이 많지 않았다. DOM 조작도 익숙하지 않아 과제를 하기 전부터 막막했다. 이번 기회로 라우터의 대한 이해도와 해시 라우터에 대해 더 깊게 배울 수 있었던 기회였다. 과제를 하면서 기본기가 부족하다는 것을 많이 깨달았고 앞으로는 javascript에 대해 더 많은 공부를 해야겠다고 생각했다. 테스트 코드는 처음이었는데 기능 테스트를 해보며 더 직관적이고 꼼꼼하게 기능 설계나 이런 부분을 깊게 생각해볼 수 있어서 좋았다.

기술적 성장

새로 학습한 개념

Route를 구현하기에 앞서 History API와 window.location의 개념을 알게 되었다.

  • Browser Route / Hash Route의 개념과 차이점

DOM 조작을 많이 못해봤었는데 이번 기회로 getElementById와 querySelector를 이용해서 요소의 속성 값을 가져오고 이벤트 처리를 해보았다. getElementById와 querySelector의 사용해야할 경우를 파악하여 사용해야겠다고 생각하였다.

코드 품질

첫번째로, 리팩토링 해야겠다고 생각한 부분은 이벤트 위임을 router의 함수 안에 넣어 사용했다. 이렇게 넣은 이유는 nav 태그 안에 a 태그를 클릭하면 브라우저는 새 페이지로 이동시키고 전체 페이지를 새로 고침하는 성격이 있어서 e.preventDefault()로 브라우저 새로 고침을 막으려고 하였으나, 페이지가 변환 될 때마다 계속 새로 고침 되는 현상이 발생했다. 그래서 route 안에서 렌더링 해주는 함수 안에서 한번 더 실행시켜주어 html을 생성시켜주었다.

export class Router {
  constructor() {
    this.routes = {};
    window.addEventListener("popstate", () => {
      this.handleRoute(window.location.pathname);
    });
  }
  addRoute(path, handler) {
    this.routes[path] = handler;
  }
  navigateTo(path) {
    history.pushState(null, "", path);
    this.handleRoute(path);
  }
  handleRoute(path) {
    const handler = this.routes[path];
    if (handler) {
      handler();
    } else {
      this.navigateTo("/404");
    }

    const nav = document.querySelector("nav");
    if (nav) {
      nav.addEventListener("click", (e) => {
        if (e.target.tagName === "A") {
          e.preventDefault();
          this.navigateTo(e.target.pathname);
        }
      });
    }
  }
} 

router 클래스 안이 아닌 click 이벤트 함수를 따로 빼서 함수를 호출할 수 있게 코드를 수정해야할거 같다.

두번째로 리팩토링 할 부분으로는 컴포넌트 설계를 했어야했는데 html만 따로 분리를 해놓고 이벤트 함수나 페이지를 렌더링하는 부분을 main 페이지에서 한번에 처리를 하는 방식으로만 구현을 했다. 이렇게 하면 안될거 같다고 생각했지만, 어떻게 나누어야 할지 모르겠어서 그냥 한 개의 파일에 연결시켜 놓았다. 기능 단위 별로 클래스나 객체로 분리를 해서 더 코드가 명확하게 설계를 시도해봐야겠다.

학습 효과 분석

이벤트 버블링/위임과 렌더링의 호출 순서에 대해 많이 배울 수 있었던 거 같다.
javascript로 전역 상태 관리에 대한 이해가 부족해서 이 부분에 대한 어려움이 있었다. 전역 상태 관리를 어떻게 이해하고 접근하여 코드를 작성해야 할지에 대해 좀 더 고민을 하려고 한다.

과제 피드백

프레임워크에서 편하게 제공하는것이여서 혼자서는 생각해보지 못한 기능 구현이었는데 이렇게 과제로 내어주셔서 감사합니다.

리뷰 받고 싶은 내용

심화 테스트 코드에서 오류 하나가 실패 났습니다. 이벤트 위임을 활용해서 네비게이션의 링크를 클릭하면 이벤트 전파를 막는 테스트 기능입니다. 오류의 내용은 body안에 header 태그가 존재 하는지에 대한 내용인데, querySelector("header")가 null이여서 그런지 테스트가 실패합니다.. home, profile 페이지가 렌더링 되었을때 모두 header 태그가 있는 것을 확인했습니다. header.js 파일에서 오류가 발생할게 없는거 같은데 왜 header 태그가 null로 발생하는지 원인을 찾지 못했습니다. 어떠한 부분을 확인해보면 좋을까요..?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant