기타

<select> 태그에서 selected 속성이 무시되는 현상

yebeen 2025. 6. 12. 20:40

 

문제 상황

<select> 태그 내부의 옵션 중, 현재 상태값과 일치하는 옵션에 selected 속성을 조건부로 삽입했지만, 페이지가 렌더링 된 이후 항상 "total" 옵션이 선택되어 있었다.

예를 들어, 아래와 같은 코드에서 sortBy 값이 "fun"인 경우에도 "total"이 선택된 상태로 나타났다.

console을 찍어보면 sortBy는 "fun"으로 정확하게 전달되고 있었지만, 실제 <select>에서는 "total"이 선택된 상태였다.

this.template = () => {
  return `
    <select id="sortList">
      <option value="total" ${sortBy === "total" ? "selected" : ""}>Total</option>
      <option value="cost" ${sortBy === "cost" ? "selected" : ""}>Cost</option>
      <option value="fun" ${sortBy === "fun" ? "selected" : ""}>Fun</option>
    </select>
  `;
};

 

원인

이 문제의 핵심 원인은 selected 속성이 HTML 파싱 시점에서만 적용된다는 점에 있다.

브라우저는 <select> 요소가 HTML로 파싱될 때, selected 속성이 붙어 있는 <option>을 찾아 초기 선택값으로 설정한다.

하지만 JavaScript에서 innerHTML을 사용하여 <select> 요소를 동적으로 렌더링 하면,

이 HTML은 파싱이 아닌 문자열로 DOM에 삽입된다.

이 경우, selected 속성은 무시되며 <select>의 .value가 명시되지 않은 경우 기본적으로 첫 번째 옵션이 선택된다.

따라서 innerHTML을 사용해 <select>를 다시 렌더링할 경우, selected 속성을 아무리 넣어도 원하는 옵션이 선택되지 않을 수 있다고 한다.

 

해결책

selected 속성을 문자열로 삽입하는 대신, 렌더링 이후에 JavaScript로 .value를 직접 설정해야 한다.

아래는 문제를 해결한 코드이다.

this.render = () => {
  this.$target.innerHTML = this.template();
  const $select = document.getElementById("sortList");
  $select.value = this.state.sortBy;
};