우아한테크코스/레벨 회고

우아한테크코스 3/15 컴포넌트 생성방법, 테코톡 스터디

jinokim 2024. 3. 16. 00:56

3일 간의 예비군을 마치고 오랜만에(?) 선릉에 도착!
도착하자마자 사람들이 하는 말이 나 없으니깐 캠퍼스가 조용했다.. 내가 그렇게 시끄러웠나ㅋㅋㅋㅋ

 

1. 의식의 흐름대로 컴포넌트만들기 수업

오늘은 크론이 의식의 흐름대로 컴포넌트를 만드는 방법 과정에 대해서 강의를 해줬다. 크루들이 웹 컴포넌트를 주로 사용했고 이에 대해서 그렇게 접근하지말고 다르게 접근해보라는 취지인 것 같은데 createElement와 appendChild로 직접 만들어서 사용하는 방식으로 구현하는 모습을 라이브코딩으로 보여줬다.

 

먼저 이번 미션의 목표에 대해서 다시 한 번 상기해주셨는데 이번 미션의 목표는 아래 두 가지였다.

  • 컴포넌트 단위를 어떻게 구성하는가?
  • 어떻게 컴포넌트를 구성하면 재사용할 수 있는 컴포넌트가 될 수 있을까?

이외의 다른 것은 지금 단계에선 생각하지 않아도 되고, 않아야했다.

아래의 내용들은 이번 미션에서 학습하고 신경을 써야하는 것이 아니었다.

  • "어떻게" 컴포넌트를 구현하는지
    • 컴포넌트를 구현하는 로직
    • 각종 컨벤션 (디렉터리, 파일 구성 방식 등)
  • 각종 스타일의 관심사 분리

 

이번 실습에서는 헤더 컴포넌트와 모달 컴포넌트를 만드는 과정에 대해서 주로 보여주셨다.

두 가지 컴포넌트에서 챙겨야할 점을 정리하고 무작정 컴포넌트를 만드는 과정을 보여주기 시작했다.

  1. "헤더" 컴포넌트
    • 레이아웃은 그대로인데 제목 내용과 버튼 이미지를 쉽게 수정할 수 있어야 한다면?
  2. "모달" 컴포넌트
    • 모달 창의 레이아웃 기준은 화면 아래에서 뻗어 올라오는 형태로 하며 모달 밖 영역은 dimmed 처리가 되어야 한다. 다른 페이지에서도 기본적인 틀은 같아야 한다면?

 

먼저 수업을 시작하면서 컴포넌트를 만드는 방법 3단계를 보여줬다.


1. 컴포넌트를 따로 만든다.
2. 컴포넌트끼리 조립한다.
3. 컴포넌트를 document에 붙인다.

1. 컴포넌트를 따로 만든다
template에 있는 html을 냅다 js에 복사한 뒤에 거기에서 사용하는 태그와 클래스 텍스트들을 createElement로 만든다.

const header = document.createElement('header');

const headerTitle = document.createElement('h1');
const imageButton = document.createElement('button');
const image = document.createElement('img');

header.classList.add('gnb');
headerTitle.classList.add('gnb__title', 'text-title');
imageButton.classList.add('gnb__button');

headerTitle.textContent = '점심 뭐 먹지?';
image.setAttribute('src', './add-button.png');


2. 컴포넌트끼리 조립한다.
createElement로 만든 태그들을 appendChild를 사용해서 붙인다. 

imageButton.appendChild(image);
header.appendChild(headerTitle);
header.appendChild(imageButton);


3. 컴포넌트를 document에 붙인다.
만들어진 컴포넌트를 메인에 붙인다.

const container = document.querySelector('#container');
container.prepend(container);

 

이렇게 시작한 뒤에 Header.js로 파일 분리하고, index에서 import해서 붙이는 과정이 컴포넌트를 만드는 과정이라고 설명해주셨다. 이렇게 생각하고 시작하면 될 미션이었는데 웹 컴포넌트를 사용해서 내장 메서드에 대해 학습하고 이런 과정들이 오버 엔지니어링이라고 선을 그었다.


나도 물론 이번 미션에서 웹 컴포넌트를 사용했지만 사실 방식은 크론의 방식이었다. (그러면 아에 웹컴 쓰지말걸..) 웹 컴포넌트 생성자에 내용들을 넣어서 appendChild를 부르면서 했는데 내 방식을 보자면

import { Caption, CaptionProps } from "../tag/caption";
import { Input, InputProps } from "../tag/input";
import { Label, LabelProps } from "../tag/label";
import { Select, SelectProps } from "../tag/select";
import { TextArea, TextAreaProps } from "../tag/textarea";
import './formItem.css';

interface FormItemProps {
  required: boolean;
  label: LabelProps;
  select?: SelectProps;
  input?: InputProps;
  textarea?: TextAreaProps;
  caption?: CaptionProps;
}

class FormItem extends HTMLDivElement {
  constructor(props: FormItemProps) {
    const { required } = props;
    super();
    this.classList.add('form-item');
    if (required) this.classList.add('form-item--required');

    this.createElements(props);
  }

  createElements(props: FormItemProps) {
    const { label, select, caption, input, textarea } = props;
    this.createLabel(label);
    this.createSelect(select);
    this.createInput(input);
    this.createTextArea(textarea);
    this.createCaption(caption);
  }

  createLabel(label: LabelProps) {
    this.appendChild(new Label(label));
  }

  createSelect(select?: SelectProps) {
    if (select === undefined) return;
    this.appendChild(new Select(select));
  }

  createInput(input?: InputProps) {
    if (input === undefined) return;
    this.appendChild(new Input(input));
  }

  createTextArea(textarea?: TextAreaProps) {
    if (textarea === undefined) return;
    this.appendChild(new TextArea(textarea));
  }

  createCaption(caption?: CaptionProps) {
    if (caption === undefined) return;
    this.appendChild(new Caption(caption));
  }
}

customElements.define('matzip-formitem', FormItem, { extends: 'div' });

export default FormItem;

 

form-item이라는 것이 재사용되니 일단 위 내용 html 복붙해두고, 거기 안에서 사용하는 태그들을 분석하면서 필요한 태그들의 컴포넌트를 만들고, form-item 안에 기본 클래스와 기본 템플릿 채우고, 필요한 태그를 컴포넌트 합성을 통해서 appendChild해주는 방식으로 구성했다.

 

이렇게 할 거라면 웹 컴포넌트 그냥 쓰지말고 만들어서 쓸 걸.. 조금 후회하긴했다.

그런데 그나마 나의 하나 효율성을 얘기해보자면 this.appendChild로써 해당 클래스 인스턴스에 붙이고 FormItem을 Form 태그에서 붙이는 방식으로 보여주어 조금 더 직관적으로 보인달까? 나는 그렇게 생각하는데 아닐지도 모른다..

 

크론이 수업을 마치면서 미션을 마무리하고 해결하는 것도 우선이지만 lms에 나와있는 고민해볼 점을 정독하면서 고민을 많이 해본다면 성장에 많은 도움이 될 것이라는 팁을 주시면서 수업을 마쳤다.

 

사실 나도 미션을 하면서 pr도 학습 목표에 대해서 적지 않았고, 구현하면서 고민한 점들만 적었던 것 같다.. 이 점에 대해서 조금 반성해야겠고, 앞으로 pr을 적을 때, 학습 목표에 대해서 어떻게 생각을 했는지, 어떻게 풀어나갔는지를 주로 적어야할 것 같았고 ste2 pr을 올릴 때, 다음 미션 영화 리뷰를 올릴 때 이 점 고려하면서 올려봐아겠다.

 

다음으로 고민해볼 점인데.. 이 점 미션을 해결하느라 정말 쉽지 않겠지만... 레벨1이 끝날 때까지 정리를 하면서 나만의 답을 적어보는 것을 목표로 진행해보자.. 정 어려우면 버퍼기간에라도 꼭

 

이렇게 오전 수업이 끝나고, 이제 step2를 rebase한 나는 발등에 불이 떨어졌다.

예비군을 다녀오느라 3일동안 미션을 하지 못했던 여파가 훅 들어왔다... 언제 기능 다 끝내고, e2e 테스트 또 언제하지...

주말에 분위기 좋은 카페에서 죽 치고 앉아서 코딩하다가 나가서 힐링하고 또 코딩하고를 반복하다보면 끝나있지 않을까???ㅋㅋㅋㅋㅋ

 

2. 테코톡 스터디

오늘 4시에는 테코톡 스터디 발표를 했다. 나는 역시 이번 주 예비군 스케쥴 때문에 차질이 생길 것 같아서 저번 주 주말에 미리 자료를 다 준비해놨고, 연습도 두 세 번 해봤어서 큰 걱정은 하지 않았었다. 

나는 오늘 마지막에 발표를 했고 그 전까지 우리 데일리 크루들의 발표를 들었다. 다들 이번 미션과 관련된 주제를 선정을 해왔다. 그래서 그런가 뭔가 더 쏙쏙 들어오는 느낌!? 질문하기도 좋았다. 특히 저번 미션에서 케빈이 랜더링 과정에 대해서 학습해보라는 얘기를 해줬어서 학습했었는데 마침 파슬리가 랜더링을 주제로 발표를 해서 질문하기도 좋았고 들을 때도 이해가 더 잘 되는 것 같았다.

 

다들 떨린다고 하면서 발표 잘 하던데~~ 다들 준비를 너무 열심히해왔고 열심히 준비를 했기 때문에 자신있게 내용을 발표할 수 있는 것 아닐까 생각한다. 다들 역시 우테코 들어올만 해!! 정말 할 때는 열심히 하는 크루들 :) 

이번 미션 빠르게 마무리하고 크루들의 발표 피드백을 적어주면 좋을 듯 하다. 서로 미흡한 점이나 잘 한 점들을 알려줘서 실제 테코톡 할 때 참고할 수 있도록 하면 좋으니깐!! 일단 이번 미션부터 해결하고;;;

나중에 영상편집해서 내 영상을 여기에 올리거나, 어느정도 미션이 해결되면 다음 주 월요일에 무중력 광장에서 사람들 모아두고 테코톡을 하듯 연습해봐도 좋겠다. 뭔가 이렇게 열심히 준비한거 많은 사람들 앞에서도 하고 싶달까?ㅋㅋ

 

이렇게 테코톡 스터디를 마무리하고 저녁을 먹고, 미션을 마구마구 해결해나가다보니,, 어느새 왔다감의 시간이

주말의 내가 열심히하면 미션을 잘 마무리할 수 있겠지.. 파이팅이다.. 진짜