[Part 11] Web Components — Props & State 패턴 + 네이밍 규칙
HTML 속성(Props)과 내부 상태(State) 패턴을 실전 코드로 정리하고, Web Components 개발 시 지켜야 할 프론트엔드 네이밍 규칙을 함께 다룹니다.
[Part 11] Web Components — Props & State 패턴 + 네이밍 규칙
Part 10에서는 Shadow DOM을 사용할지 말지 판단하는 기준을 정리했다.
이번 글에서는 Web Components에서 외부 값과 내부 상태를 어떻게 다룰지 알아본다.
React나 Vue를 사용하면 props와 state라는 말을 자주 듣는다.
Web Components에도 비슷한 개념이 있다.
다만 Web Components는 React처럼 정해진 상태 관리 방식이 있는 것은 아니기 때문에 직접 규칙을 정해야 한다.
1. props와 state란?
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
props는 외부에서 컴포넌트로 전달되는 값이다.
state는 컴포넌트 내부에서 관리하는 값이다.
예를 들어 사용자 카드 컴포넌트가 있다고 해보자.
<user-card
name="사용자"
role="관리자"
></user-card>
여기서 name과 role은 외부에서 전달되는 값이다.
이런 값은 props에 가깝다.
반면 카드가 열려 있는지, 선택되었는지, 로딩 중인지 같은 값은 컴포넌트 내부 state로 볼 수 있다.
2. Attribute란?
Web Components에서 외부 값을 전달하는 가장 기본적인 방법은 attribute다.
<my-button
variant="primary"
size="large"
>
저장
</my-button>
variant와 size가 attribute다.
JavaScript에서는 getAttribute()로 값을 가져온다.
const variant = this.getAttribute('variant');
const size = this.getAttribute('size');
attribute는 HTML에 직접 작성할 수 있어서 선언적이다.
정적 HTML, 서버 렌더링, 블로그 코드 예제에서도 이해하기 쉽다.
3. Property란?
Property는 JavaScript 객체의 속성이다.
const button = document.querySelector('my-button');
button.variant = 'primary';
attribute는 HTML에 작성하는 값이고, property는 JavaScript로 다루는 값이다.
4. Attribute와 Property 차이
| 구분 | Attribute | Property |
|---|---|---|
| 사용 위치 | HTML | JavaScript |
| 값 타입 | 문자열 중심 | 문자열, 숫자, 불리언, 객체, 배열 가능 |
| 예시 | variant="primary" | button.variant = 'primary' |
attribute는 기본적으로 문자열이다.
복잡한 객체나 배열을 전달해야 한다면 property가 더 적합하다.
5. observedAttributes로 변경 감지하기
attribute가 변경될 때 화면도 바꾸고 싶다면 observedAttributes와 attributeChangedCallback()을 사용한다.
class MyButton extends HTMLElement {
static get observedAttributes() {
return ['variant', 'size'];
}
connectedCallback() {
this.render();
}
attributeChangedCallback() {
this.render();
}
render() {
const variant = this.getAttribute('variant') || 'default';
const size = this.getAttribute('size') || 'medium';
this.innerHTML = `
<button>
${variant} / ${size}
</button>
`;
}
}
customElements.define('my-button', MyButton);
observedAttributes는 감시할 attribute 목록을 정한다.
attributeChangedCallback()은 감시 중인 attribute가 변경될 때 실행된다.
render()는 현재 값에 맞게 화면을 다시 그린다.
6. getter와 setter
property처럼 값을 읽고 쓰려면 getter와 setter를 만들 수 있다.
class MyButton extends HTMLElement {
get variant() {
return this.getAttribute('variant');
}
set variant(value) {
this.setAttribute('variant', value);
}
}
이제 JavaScript에서 다음처럼 사용할 수 있다.
const button = document.querySelector('my-button');
button.variant = 'primary';
console.log(button.variant);
get variant()는 값을 읽을 때 실행된다.
set variant(value)는 값을 설정할 때 실행된다.
7. Boolean 속성 다루기
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
도킷 - 채팅, 일본친구, 일본여자, 외국친구
disabled 같은 boolean 속성은 값보다 존재 여부가 중요하다.
<my-button disabled>
저장
</my-button>
JavaScript에서는 hasAttribute()로 확인할 수 있다.
const disabled = this.hasAttribute('disabled');
property로 만들면 다음과 같다.
get disabled() {
return this.hasAttribute('disabled');
}
set disabled(value) {
if (value) {
this.setAttribute('disabled', '');
} else {
this.removeAttribute('disabled');
}
}
이 방식은 HTML 기본 요소의 disabled 처리와 비슷하다.
8. 내부 state 관리하기
state는 컴포넌트 내부에서만 사용하는 값이다.
예를 들어 토글 버튼을 만들어보자.
class ToggleButton extends HTMLElement {
constructor() {
super();
this._pressed = false;
}
connectedCallback() {
this.render();
}
toggle() {
this._pressed = !this._pressed;
this.render();
}
render() {
this.innerHTML = `
<button>
${this._pressed ? 'ON' : 'OFF'}
</button>
`;
this.querySelector('button')
.addEventListener('click', () => {
this.toggle();
});
}
}
customElements.define('toggle-button', ToggleButton);
this._pressed는 내부 상태다.
버튼을 클릭할 때마다 true와 false가 바뀐다.
상태가 바뀌면 render()를 다시 호출해서 화면을 갱신한다.
9. 언더스코어를 붙이는 이유
내부에서만 사용하는 값에는 관례적으로 언더스코어를 붙이는 경우가 많다.
this._value
this._open
this._selected
this._pressed
이것은 JavaScript에서 강제하는 문법은 아니다.
다만 이 값이 외부에서 직접 다루기 위한 값이 아니라 내부 상태라는 것을 표시하기 위한 관례다.
10. 상태 변경을 외부에 알리기
내부 state가 바뀌었을 때 외부에 알려야 한다면 CustomEvent를 사용한다.
this.dispatchEvent(
new CustomEvent('value-change', {
bubbles: true,
composed: true,
detail: {
value: this._value
}
})
);
컴포넌트 내부 상태는 내부에서 관리한다.
외부에 알려야 할 때만 이벤트를 발생시킨다.
11. 네이밍 규칙
Web Components를 만들 때는 이름 규칙을 정해두는 것이 좋다.
- 태그 이름은 소문자와 하이픈을 사용한다.
- attribute 이름도 소문자와 하이픈을 사용한다.
- 이벤트 이름도 소문자와 하이픈을 사용한다.
- property 이름은 JavaScript 관례에 맞게 camelCase를 사용할 수 있다.
예시는 다음과 같다.
<ui-button
button-size="large"
variant="primary"
>
저장
</ui-button>
component.buttonSize = 'large';
component.addEventListener('value-change', handler);
12. 정리
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
Web Components에서는 외부 값과 내부 상태를 직접 설계해야 한다.
- attribute는 HTML에서 전달하는 값이다.
- property는 JavaScript에서 다루는 값이다.
- attribute는 기본적으로 문자열이다.
- 객체나 배열은 property로 다루는 것이 좋다.
- boolean 값은 hasAttribute()로 다룰 수 있다.
- state는 컴포넌트 내부에서 관리하는 값이다.
- 상태 변경을 외부에 알릴 때는 CustomEvent를 사용한다.
- 태그, attribute, 이벤트 이름은 소문자와 하이픈 조합을 추천한다.
다음 Part에서는 Web Components와 React를 비교하고 함께 사용하는 방법을 알아본다.
AD
제휴 광고
일부 링크는 제휴 링크이며, 구매 또는 가입 시 일정 수수료를 받을 수 있습니다.
AD
'Web components' 카테고리의 다른 글
전체보기- [Part 7] Web Components — 고급 스타일링 전략 2026.05.13
- [Part 8] Web Components — Form 연동과 ElementInternals 2026.05.20
- [Part 9] Web Components — static template 패턴 & 메모리 최적화 2026.05.27
- [Part 10] Web Components — Shadow DOM 있는 것 vs 없는 것 2026.06.03
- [Part 11] Web Components — Props & State 패턴 + 네이밍 규칙 현재 글
- [Part 12] Web Components vs React — 실전 비교와 함께 쓰는 법 2026.06.04









