안티 패턴이란 실제 많이 사용되는 패턴이지만 비효율적이거나 비생산적인 패턴을 의미한다.
안티패턴은 성능, 디버깅, 유지보수, 가독성등에 있어 부정적인 영향을 줄 수 있기 때문에 지양해야하는 패턴이다.
어떤 부분들을 조심해야 하는지, 한번 알아보도록 하자.
<div onClick />로 선언하기<div>는 기본적으로 포커스가 불가능.<button/>은 포커스 스타일, 클릭 스타일, 활성화 스타일이 적용되지만, <div>는 적용되지 않음.<div onClick={handleClick}>
정말 클릭 가능하기만 한 div
</div> // 안티 패턴!
위의 빠져있는 요소들을 하나하나 추가해줘도 되겠지만, button을 사용하면 한 번에 해결되는 문제이다.
버튼 역할이라면<button>을 사용, 링크 역할이라면<a href="..."/>를 사용하도록 하자.
<div onClick={handleClick} tabIndex={0} onKeyDown={(e) => e.key === "Enter" && handleClick()}>
덕지덕지 붙은 클릭가능한 div
</div> // 이렇게 써주는 방법도 있겠지만...
<button onClick={handleClick}>깔끔한 버튼</button> // 그냥 button 쓰자!
alt 속성이 없는 <img> 태그<img src="/logo.png" /> // 안티 패턴!
alt 속성이 없으면 스크린 리더가 이미지를 무시.모든 이미지에 alt 속성을 추가하거나, 장식용 이미지라면 alt=""로 비워두도록 하자.
<img src="/logo.png" alt="웹사이트 로고" />
<img src="/icon.png" alt="" />
<p style={{ color: "red" }}>비밀번호가 틀렸습니다.</p> // 안티 패턴!
아이콘 + 텍스트를 함께 사용하거나, ARIA 속성을 활용해 추가적인 설명 제공해주도록 하자.
<p style={{ color: "red" }}> ❌ 비밀번호가 틀렸습니다. </p> // 아이콘 추가
<p role="alert">비밀번호가 틀렸습니다.</p> // 보조기술이 감지할 수 있도록 ARIA 추가
label 없이 <input> 사용하기<input id="username" type="text" /> // 안티 패턴!
<input>만 있고 label이 없으면 스크린 리더가 어떤 입력 필드인지 설명하지 못함.반드시 <label>을 사용해주거나, 시각적으로 숨겨야 한다면 aria-label 또는 aria-labelledby를 활용하자.
<label htmlFor="username">사용자 이름</label>
<input id="username" type="text" /> // react에서는 for -> htmlFor
<input type="text" aria-label="사용자 이름" /> // 시각적으로 숨긴 라벨