바닐라 JS로 SPA를 구현하는 중, a태그 클릭 시 화면 이동이 아닌 같은 페이지에 element들이 중복 렌더링되는 오류가 발생하였다🤯
각 페이지를 렌더링할 때, index.html의 root 태그 안에 요소들이 추가된다.
👉 root 태그 아래 header, section, main, footer 가 추가된 것을 확인할 수 있다.
router.js의 render부분을 살펴보자.
document.querySelector(this.rootElementId)로 index.html의 root를 받아오고
rootElement.innerHtml = ''으로 root를 초기화해준 후
rootElement.appendChild(view)로 root에 view(page) 컴포넌트를 추가해 주어야 한다.
👉 하지만 root 초기화가 이루어지지 않고, 기존 elements 아래에 같은 element들이 중복으로 추가되었다😨
view 컴포넌트를 확인해 보았다.
Component를 불러올 때, Component의 render부분이 root에 추가되어야 하는데 render의 return 값을 설정하지 않았다.
render 안의 컴포넌트들을 div 등으로 감싸서 return 해주어야 하는데 header, footer을 포함한 html 요소들을 감싸기 위해 div를 또 생성하는 것이 괜히 불편했다.
나는 root 태그 안에 직접 요소들을 추가해주기 위해 타겟 요소로 root를 불러온 후 append 해주기만 했다. 그러니 라우터의 render가 이루어지지 않고, root에 계속 중복으로 append만 되었던 것....😵
멘토님께 div 하위에 heaer, footer을 추가하는 것이 불편했다 말씀드리니 DocumentFragment를 알려주셨다.
DocumentFragment는 특별한 DOM 노드 타입으로, 여러 노드로 구성된 그룹을 감싸 다른 곳으로 전달하게 해주는 wrapper처럼 동작힙니다.
문서에 있는 다른 노드를 DocumentFragment에 추가할 수 있는데, DocumentFragment를 문서 어딘가에 삽입하면 DocumentFragment는 사라지고 DocumentFragment에 추가한 노드만 남습니다.
DocumentFragment는 메모리에서만 정의되는 경량화된 문서 객체이다. DOM에 추가하면 DocumentFragment node는 사라지고 자식 node만 추가된다. 한마디로 투명 포장지같은 존재..
이 DocumentFragment라는 투명 포장지에 element들을 담아보자.
root를 불러오는 타겟 요소를 지워주고
document.createDocumentFragment()
로 DocumentFragment를 생성한 후 요소들을 append 해주었다.
마지막으로 DocumentFragment를 return 해주면..
👉 이렇게 root 하위로 DocumentFragment에 담아둔 element들이 추가되었다. 투명 포장지는 보이지 않는다!
화면도 잘 이동하고, 렌더링도 잘 실행된다.
참고 사이트
https://ko.javascript.info/modifying-document#document-fragment