[Part 8] Web Components — Form 연동과 ElementInternals
ElementInternals API로 커스텀 엘리먼트를 네이티브 form과 연동하는 방법. formAssociated, setFormValue, validity 구현 패턴을 다룹니다.
[Part 8] Web Components — Form 연동과 ElementInternals
Part 7에서는 Web Components의 고급 스타일링 전략을 알아봤다.
이번 글에서는 Web Components를 form과 연동하는 방법을 알아본다.
form은 사용자가 입력한 데이터를 서버로 보내거나 JavaScript에서 처리할 때 사용하는 HTML 요소다.
로그인, 회원가입, 검색, 주문서 같은 화면에서 자주 사용된다.
1. 기본 form 이해하기
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
일반적인 form은 다음처럼 작성한다.
<form>
<input name="username" value="user1" />
<button type="submit">전송</button>
</form>
input의 name은 데이터의 이름이다.
value는 실제 값이다.
form이 제출되면 username=user1 같은 형태로 데이터가 전달된다.
2. 커스텀 요소는 기본적으로 form에 포함되지 않는다
직접 만든 커스텀 요소는 기본적으로 form 데이터에 자동 포함되지 않는다.
<form>
<my-input name="username"></my-input>
<button type="submit">전송</button>
</form>
이렇게 작성해도 <my-input>은 일반 input처럼 form 데이터에 자동으로 들어가지 않는다.
브라우저 입장에서는 <my-input>이 실제 입력 요소인지 알 수 없기 때문이다.
3. Form-associated Custom Elements
커스텀 요소를 form과 연결하려면 form-associated custom element로 만들어야 한다.
이를 위해 class에 다음 설정을 추가한다.
static formAssociated = true;
이 코드는 이 커스텀 요소가 form과 연결될 수 있다는 의미다.
class MyInput extends HTMLElement {
static formAssociated = true;
}
customElements.define('my-input', MyInput);
4. ElementInternals란?
ElementInternals는 커스텀 요소가 form과 연결되기 위해 사용하는 내부 제어 객체다.
이 객체를 사용하면 커스텀 요소도 form에 값을 전달할 수 있다.
ElementInternals는 attachInternals()로 만든다.
class MyInput extends HTMLElement {
static formAssociated = true;
constructor() {
super();
this.internals = this.attachInternals();
}
}
customElements.define('my-input', MyInput);
this.attachInternals()는 현재 커스텀 요소와 연결된 내부 제어 객체를 만든다.
5. setFormValue()
form에 전달할 값을 설정할 때는 setFormValue()를 사용한다.
this.internals.setFormValue('hello');
이 코드는 커스텀 요소의 form 제출 값을 hello로 설정한다.
6. 간단한 my-input 만들기
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
톨루나 팝업패널리워드 회원가입
class MyInput extends HTMLElement {
static formAssociated = true;
constructor() {
super();
this.internals = this.attachInternals();
}
connectedCallback() {
this.innerHTML = `
<input type="text" />
`;
const input = this.querySelector('input');
input.addEventListener('input', () => {
this.internals.setFormValue(input.value);
});
}
}
customElements.define('my-input', MyInput);
HTML에서는 다음처럼 사용한다.
<form>
<my-input name="username"></my-input>
<button type="submit">전송</button>
</form>
사용자가 내부 input에 값을 입력하면 setFormValue()가 그 값을 form에 전달할 값으로 설정한다.
7. name 속성의 역할
form에서 name은 데이터의 key 역할을 한다.
<input name="username" value="user1" />
이 경우 form 데이터는 username이라는 이름으로 전달된다.
커스텀 요소도 마찬가지로 name이 있어야 form 데이터에서 어떤 이름으로 전달될지 정해진다.
<my-input name="username"></my-input>
8. value 프로퍼티 만들기
input처럼 사용하려면 value 프로퍼티를 만들어두는 것이 좋다.
class MyInput extends HTMLElement {
static formAssociated = true;
constructor() {
super();
this.internals = this.attachInternals();
this._value = '';
}
get value() {
return this._value;
}
set value(newValue) {
this._value = newValue;
this.internals.setFormValue(newValue);
}
}
get value()는 값을 읽을 때 실행된다.
set value()는 값을 설정할 때 실행된다.
this._value는 컴포넌트 내부에서 관리하는 값이다.
9. 유효성 검증
form에서는 required 같은 검증이 중요하다.
ElementInternals는 유효성 상태도 설정할 수 있다.
this.internals.setValidity(
{
valueMissing: true
},
'값을 입력해주세요.'
);
값이 정상일 때는 빈 객체를 전달한다.
this.internals.setValidity({});
이 기능을 사용하면 커스텀 요소도 브라우저의 form validation 흐름에 참여할 수 있다.
10. 언제 ElementInternals를 사용할까?
ElementInternals는 모든 Web Component에 필요한 것은 아니다.
주로 form과 직접 연동되어야 하는 컴포넌트에서 사용한다.
- 커스텀 input
- 커스텀 checkbox
- 커스텀 radio
- 커스텀 select
- 커스텀 date picker
- 커스텀 file uploader
단순 버튼, 카드, 모달에는 보통 필요하지 않다.
11. 정리
AD
제휴 광고 · 일부 링크는 수수료를 받을 수 있습니다
커스텀 요소는 기본적으로 form에 자동 연동되지 않는다.
- form과 연동하려면
static formAssociated = true를 사용한다. attachInternals()로 ElementInternals 객체를 만든다.setFormValue()로 form에 제출될 값을 설정한다.nameattribute는 form 데이터의 key 역할을 한다.setValidity()로 유효성 상태를 설정할 수 있다.
다음 Part에서는 static template 패턴과 메모리 최적화를 알아본다.
AD
제휴 광고
일부 링크는 제휴 링크이며, 구매 또는 가입 시 일정 수수료를 받을 수 있습니다.
AD
'Web components' 카테고리의 다른 글
전체보기- [Part 7] Web Components — 고급 스타일링 전략 2026.05.13
- [Part 8] Web Components — Form 연동과 ElementInternals 현재 글
- [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 패턴 + 네이밍 규칙 2026.06.04
- [Part 12] Web Components vs React — 실전 비교와 함께 쓰는 법 2026.06.04










