컴포넌트란?
컴포넌트는 다양한 분야에서 여러 문맥에 따라 사용되기 때문에, 한 마디로 정의하는 것은 쉽지 않다. 디자이너나 PM에게는 “하나의 역할을 하기 위해 모은 디자인 요소”가 UI 컴포넌트고, 프론트엔드 개발자에겐 "하나의 기능 구현을 위한 여러 종류의 코드 묶음"이 컴포넌트이다.
신기하게도 프론트엔드 개발자 입장에서 코드 컴포넌트를 열심히 만들고, 디자이너 입장에서 열심히 UI 컴포넌트를 만들다 보면 비슷하게 맞아 떨어지는 경우가 많다. 유저가 편하게 사용할 수 있는 애플리케이션을 제작해야 하기 때문에, 자연스럽게 기능 위주로 코드와 디자인이 분류되기 때문이다. 아예 디자이너와 프론트엔드 개발자가 합심해서 하나의 완성된 애플리케이션 제작을 위한 디자인 시스템을 만들기도 한다.
이런 점들을 종합해서 컴포넌트의 정의를 내려보자면, “하나의 역할을 하기 위해 모인 무언가의 집합”이라고 할 수 있다.
아고라 스테이츠의 컴포넌트 분류하기
아고라 스테이츠의 핵심 기능은 무엇일까? 아고라 스테이츠는 토의장의 성격을 가지고 있다. 따라서 가장 중요한 토의 주제와 내용을 담고 있는 Discussion을 생성, 조회, 수정, 삭제(CRUD)하는 기능이 아고라 스테이츠의 핵심 기능이라고 볼 수 있다.
이 각각의 Discussion을 묶은 컨테이너인 Discussions가 하나의 컴포넌트입니다. 또 Discussions 내부에 있는 각각의 Discussion들 또한 하나의 컴포넌트라고 할 수 있다.
Discussion 컴포넌트 만들기
Github Discussion 컴포넌트를 참고하여 직접 나만의 Discussion 컴포넌트를 제작해보자. 샘플데이터는 다음과 같다.
{
"id": "D_kwDOHOApLM4APXTS",
"createdAt': "2022-04-22T14:08:33Z",
"title": "[notice] 좋은 질문하는 법",
"url": "https://github.com/codestates-seb/agora-states-fe/discussions/4",
"author": "kimploo",
"answer": null,
"bodyHTML":
"... 생략",
"avatarUrl":
"https://avatars.githubusercontent.com/u/12145019?s=64&u=5c97f25ee02d87898457e23c0e61b884241838e3&v=4",
}
위 기획을 HTML로 작성하면 아래와 같다. Discussion 컴포넌트는 <li>요소로 구성되어 있고, <li>요소의 내부에는 세 개의 <div>요소가 들어있다. 각각의 <div>요소의 내부에 사진을 넣기 위해 <img> 요소를 사용했고, 제목을 표현하기 위해 <h2>요소를 사용했다.
<li class="discussion__conatiner">
<div class="discussion__avatar--wrapper">
<img class="discussion__avatar--image"
src="https://avatars.githubusercontent.com/u/12145019?s=64&u=5c97f25ee02d87898457e23c0e61b884241838e3&v=4"
alt="avatar of kimploo">
</div>
<div class="discussion__content">
<h2 class="discussion__title"><a href="https://github.com/codestates-seb/agora-states-fe/discussions/6">[notice] 좋은 질문하는 법</a></h3>
<div class="discussion__information">kimploo / 2022-04-22T14:08:33Z</div>
</div>
<div class="discussion__answered">☑</div>
</li>
class명은 각 요소의 역할과 기능이 표현되도록 작성하는 것이 좋다. 기획 단계에서 어떤 HTML 요소를 쓸지, 클래스 이름은 무엇으로 할지 적어두면 좋다.
index.html 파일에 위 HTML을 작성한 후 열어보면 아래와 같은 화면이 보입니다. CSS를 추가하지 않았기 때문에 아직 원하는 화면이 나오지가 않습니다. Unit6에서 학습한 flexbox속성을 사용하여 Discussion 내부에 있는 요소를 배치해 보세요. 우선 왼쪽, 가운데, 오른쪽 박스에 적절한 간격을 줘봅시다. 왼쪽, 오른쪽 요소를 맨 끝으로 보내기 위해서는 flexbox justify-content 속성의 space-between 값을 사용하는게 좋습니다. 아고라 스테이츠의 Discussion의 CSS 속성을 개발자 도구로 확인해서 적용하는 것도 좋습니다. 아래 사례는 블로그 플렛폼 Medium의 실제 개발 사례입니다. 마찬가지로 space-between 을 사용하고 있으니 참고하세요.
디스커션 나열하기
수천개의 데이터를 index.html 에 있는 각각의 HTML 요소에 넣으려 아래처럼 하드코딩하는 것이다.
<ul class="discussions__container">
<li class="discussion__container">
<div class="discussion__avatar--wrapper">
<img class="discussion__avatar--image"
src="https://avatars.githubusercontent.com/u/12145019?s=64&u=5c97f25ee02d87898457e23c0e61b884241838e3&v=4"
alt="avatar of kimploo">
</div>
<div class="discussion__content">
<h2 class="discussion__title">
<a href="https://github.com/codestates-seb/agora-states-fe/discussions/6">[notice] 좋은 질문하는 법</a></h2>
<div class="discussion__information">kimploo / 2022-04-22T14:08:33Z</div>
</div>
<div class="discussion__answered"><p>☑</p></div>
</li>
<li class="discussion__container">
<!-- 생략 -->
</li>
<li class="discussion__container">
<!-- 생략 -->
</li>
<!-- ... -->
</ul>
그러나 nn개(아마 수천~수만이 될 수도 있다)의 요소를 모두 하드코딩하는 것은 너무 비효율적인 작업이다. 더군다나 프론트엔드 개발자라면 훨씬 더 많은 양의 데이터를 다루게 될 것이기 때문에 하드코딩으로는 한계가 있다. 중간에 데이터를 수정하는 것도 너무 어렵다.
배열이 주어져 있고, 그 배열의 각 요소를 모두 사용하려면 반복문을 사용하면 된다. HTML은 프로그래밍 언어가 아니기 때문에 반복문이 없지만, DOM을 활용하면 HTML 요소를 JavaScript로 조작할 수 있다.
하나의 Discussion 컴포넌트를 표현하기 위한 HTML은 아래와 같다. 아래 코드랑 같은 DOM 구조를 만들어보자. HTML을 DOM 구조로 변환해주는 DOM Viewer을 활용하면, DOM 구조를 직접 눈으로 확인할 수 있다.
<li class="discussion__container">
<div class="discussion__avatar--wrapper">
<img class="discussion__avatar--image"
src="https://avatars.githubusercontent.com/u/12145019?s=64&u=5c97f25ee02d87898457e23c0e61b884241838e3&v=4"
alt="avatar of kimploo">
</div>
<div class="discussion__content">
<h2 class="discussion__title">
<a href="https://github.com/codestates-seb/agora-states-fe/discussions/6">[notice] 좋은 질문하는 법</a></h3>
<div class="discussion__information">kimploo / 2022-04-22T14:08:33Z</div>
</div>
<div class="discussion__answered"><p>☑</p></div>
</li>
개발자 도구에서 연습하기
개발자 도구에서 li.discussion__container 를 만들어보자.
const li = document.createElement('li'); // li 요소 생성
li.className = 'discussion__container'; // 클래스 이름 지정
<li>요소 내부에 들어갈 세 개의 <div>요소도 만들어 보자. div.discussion__avatar--wrapper, div.discussion__content, div.discussion__answered 라고 하면 되겠다.
const avatarWrapper = document.createElement('div');
avatarWrapper.className = 'discussion__avatar--wrapper';
const discussionContent = document.createElement('div');
discussionContent.className = 'discussion__content';
const discussionAnswered = document.createElement('div');
discussionAnswered.className = 'discussion__answered';
아바타 프로필 사진이 들어갈 <img> 요소도 추가하고 src, alt 속성을 agoraStatesDiscussions의 첫 번째 요소에 있는 데이터로 넣어준다.
const avatarImg = document.createElement('img');
avatarImg.src = agoraStatesDiscussions[0].avatarUrl;
avatarImg.alt = 'avatar of ' + agoraStatesDiscussions[0].author;
avatarWrapper.append(avatarImg);
DOM append 메서드를 이용하여, 위에서 생성한 <div>요소들을 li.discussion__container의 자식 요소로 추가할 수 있다.
li.append(avatarWrapper, discussionContent, discussionAnswered);
이렇게 잘 생성한 li.discussion__container 를 ul.discussions__container 에 넣어보자. 아래와 같이 새로운 Discussion이 생성된 것이 보인다면 성공이다.
const ul = document.querySelector('ul.discussions__container');
ul.append(li);
위와 유사한 과정을 거치면 index.html 을 브라우저에서 열 때 agoraStatesDiscussions 배열의 nn개 요소의 정보를 보여줄 수 있다. script.js 파일 내부에는 agoraStatesDiscussions 배열의 모든 데이터를 반복문을 사용하여 화면에 렌더링하는 함수인 render()가 이미 작성되어 있다.
완성된 코드
'📌 TOY-PROJECT > 2303 문답게시판' 카테고리의 다른 글
[연습 프로젝트] 문답 게시판_서버 개발 (0) | 2023.04.09 |
---|---|
[연습 프로젝트] 문답 게시판 _ pagination & local storage 코드 분석 (0) | 2023.03.18 |
[연습 프로젝트] 문답 게시판_클라이언트 : 페이지네이션 등 (0) | 2023.03.16 |
[연습 프로젝트] 나만의 아고라 스테이츠 만들기 (0) | 2023.03.12 |