[TIL] 0308

yoon Y·2022년 3월 9일
0

2022 - TIL

목록 보기
53/109

TypeScript Project

템플릿 컴포넌트 성능 개선 실패

constructure함수에서 컴포넌트 자신의 dom을 만들고, 자식 컴포넌트를 생성해 연결해주려면
인스턴스 생성 시에 해당 컴포넌트가 사용할 태그 이름을 props으로 넣어줘야하는데,
그럴 경우 같은 컴포넌트여도 각자 다른 태그로 생성될 수 있어, 컴포넌트 통일성에 있어서 좋지 않다고 판단했다.

템플릿 기능을 어느정도 포기하고 컴포넌트를 선언할 때마다 constructor함수 안에 일일이 돔을 만드는 방법도 있지만 기본 메소드들까지 매번 실행 시켜줘야하기 때문에 템플릿의 편리함을 가져갈 수가 없었다.

결국 다시 되돌려서 부모 컴포넌트 템플릿에 자식 컴포넌트들이 연결될 태그들을 각각 만들어주고, 부모 컴포넌트 렌더링 이후 자식 컴포넌트들을 생성해 연결해주는 방법을 가져가기로 했다.
부모 상태 변화에 영향을 받지 않는 컴포넌트가 재렌더링되는 문제는 가상돔을 구현하는 걸로 해결해야할 것 같다.

라우터 구현

history API를 이용해 url이동시키기

1. 필요한 함수 선언

  • route-push라는 커스텀 이벤트를 발생시키고 이동할 url을 event객체에 할당하는 함수
    // router.ts
    export const push = (nextUrl: string) => {
      window.dispatchEvent(
        new CustomEvent('route-push', {
          detail: {
            nextUrl,
          },
        }),
      );
    };
  • window객체에 route-push 커스텀 이벤트의 리스너 콜백함수를 등록하는 함수.
    리스너 함수는 event객체에서 이벤트 발생 시 저장한 이동 url을 꺼내와서 history.pushState를 실행해 url을 이동 시켜준 후, route함수를 실행시킨다.
     // router.ts
     export const pushRouter = (onRoute: () => void) => {
      window.addEventListener(ROUTE_PUSH_EVENT_NAME, (e: CustomEventType) => {
       const { nextUrl } = e.detail;
       if (nextUrl) {
         history.pushState(null, null, nextUrl);
         onRoute();
       }
     });
    };
  • 현재 페이지에서 pathName을 받아온 후 매칭된 컴포넌트를 생성하는 함수
    // routes.ts
    const route = (target: Element) => {
      const { pathname } = window.location;
      switch (pathname) {
        case '/':
          new Home(target);
          break;
        case '/HexColors':
          new HexColors(target);
          break;
        case '/RandomQuotes':
          new RandomQuotes(target);
          break;
        default:
          console.log('not found page');
      }
    };

2. 처음 app이 실행 될 때 전역 객체에 이벤트를 등록해주기 위해 App컴포넌트에 router함수를 실행시킨다

  // App.ts

  ...
  
  setInitRouter(target: Element) {
    router(target);
    pushRouter(() => {
      router(target);
    });
    replaceRouter(() => {
      router(target);
    });
    popStateRouter(() => {
      router(target);
    });
  }

   mounted() {
    ...
    this.setInitRouter($main);
  }

3. url이동이 필요한 경우 push함수를 불러와 실행시킨다

  handleClickContent(e: Event) {
    console.log('handler');
    const { target } = e;
    if (target instanceof HTMLElement) {
      const { url } = target.dataset;
      push(url);
    }
  }

webpack devServer Cannot GET문제

문제점
devServer로 브라우저 실행 시 라우터로 url을 이동했을 때 Cannot GET문구가 뜨면서 제대로 동작하지 않았다

해결책

// webpack.config.js
module.exports = {
  ...
  output: {
    ...
    publicPath: '/'
  },
  devServer: {
    historyApiFallback: true, // 이걸 추가해줘야 했음
  },
}
profile
#프론트엔드

0개의 댓글