className과 classList.add의 동작원리

taeyooooon·2023년 8월 7일
0
post-thumbnail

focus된 요소에 스크롤 되는 기능을 구현하던 중 특정 액션을 취하면 focus된 요소에 적용했던 스타일이 초기화가 되는 문제가 있었다.

아래 컴포넌트의 id를 가진 DOM에 접근해서 해당 요소에 클래스네임을 추가하는 로직으로 구현하고있었는데 아래 display prop이 변경되는 액션을 취할 때 기존 클래스네임이 초기화되었다.

문제가 발생한 코드

export default function Component({ children, className = '', id, display = true }: Props) {

  return (
    <section
      className={clsx(
        'w-full',
        border ? '스타일코드' : '스타일코드2',
    	display ? '스타일코드' : '스타일코드2',
        className,
      )}
      id={id}
    >
      {children}
    </section>
  )
}

아래 context api로 focus된 요소에 직접 DOM 접근을 해서 className을 추가하고 제거하는 방식으로 구현했는데, classList를 remove하는 로직이 포함된 useEffect 클린업이나 onInputBlur 둘다 콘솔이 안찍히는걸 보면 context Api의 문제가 아닌 다른 요소의 문제라고 판단했다.

context api
...
const onInputBlur = () => {
    setFocusedInput(undefined)
  }

useEffect(() => {
    if (focusedInput) {
      const focusElement = document.getElementById(focusedInput)
      if (focusElement) {
        focusElement.scrollIntoView({ behavior: 'smooth' })
        focusElement.classList.add('focusHighlight')
        return () => {
          focusElement.classList.remove('focusHighlight')
        }
      }
    }
  }, [focusedInput])
...

디버깅을 한참 해보다가 뭔가 className가 classList.add로 추가된 클래스를 덮어버리는거 같아서 className과 classList.add 동작원리에 대해 찾아보았다.

className

className을 사용하면 기존 클래스를 덮어쓰게 되므로, 기존 클래스 목록을 완전히 대체하는 방식으로 작동한다.

<div id="element" className='initClassName'/>
  
const element = document.getElementById("element");
console.log(element.className); // "initClassName"
element.className = "class name";
console.log(element.className); // "class name"

classList.add

classList.add을 사용하면 기존 클래스 목록을 변경하지 않으면서 새로운 클래스를 추가한다.

<div id="element" className='initClassName'/>
  
const element = document.getElementById("element");
console.log(element.className); // "initClassName"
element.classList.add("classList", "add");
console.log(element.className); // "initClassName classList add"

참고한 글

https://stackoverflow.com/questions/69361432/difference-between-classname-and-classlist

profile
응애🐣 프론트엔드

1개의 댓글

comment-user-thumbnail
2023년 8월 7일

많은 도움이 되었습니다, 감사합니다.

답글 달기

관련 채용 정보