개요
- React + TypeScript 프로젝트를 진행하던 중 li 태그에 onClick 속성을 추가하니 Eslint 에러가 발생했다.
- 위 에러가 발생하는 이유와 해결 방법에 대해 알아보자.
코드
type RestaurantRowProps = {
restaurant:Restaurant
}
function RestaurantRow({ restaurant }:RestaurantRowProps) {
const [, cartStore] = useCartStore();
const handleClick = (food:Food) => () => {
cartStore.addCart(food);
};
return (
<tr>
<td>{restaurant.name}</td>
<td>
<ul>
{restaurant.menu.map((food) => (
<li key={food.id} onClick={handleClick(food)}> // ❗️Error
<img src={food.image} alt={food.image} />
<p>{food.name}</p>
<p>{`${convertKRW(food.price)}원`}</p>
</li>
))}
</ul>
</td>
</tr>
);
}
export default RestaurantRow;
원인
- 비대화형 HTML 요소와 비대화형 ARIA의 역할은 UI의 컨텐츠 및 컨테이너를 나타내는 것이다.
- 그러므로 이들은 Mouse, Keyboard 이벤트 핸들러를 지원하지 않는다.
- li 요소는 비대화형 HTML 요소이다.
해결방법
1. Mouse, Keyboard 이벤트는 가급적 대화형 요소에만 사용한다.
대표적인 대화형 요소로는 button
, link
등이 있다.
type RestaurantRowProps = {
restaurant:Restaurant
}
function RestaurantRow({ restaurant }:RestaurantRowProps) {
const [, cartStore] = useCartStore();
const handleClick = (food:Food) => () => {
cartStore.addCart(food);
};
return (
<tr>
<td>{restaurant.name}</td>
<td>
<ul>
{restaurant.menu.map((food) => (
<li key={food.id}>
<button type="button" onClick={handleClick(food)}> // ✅ button에 onClick 추가
<img src={food.image} alt={food.image} />
<p>{food.name}</p>
<p>{`${convertKRW(food.price)}원`}</p>
</button>
</li>
))}
</ul>
</td>
</tr>
);
}
export default RestaurantRow;
2. role = "presentation" 속성 추가
presentation 속성을 추가함으로써 요소의 컨텐츠 또는 컨테이너 의미 값이 그대로 유지된다.
또한, 해당 요소를 무시해야 한다는 것을 보조 기술에게 알려준다.
type RestaurantRowProps = {
restaurant:Restaurant
}
function RestaurantRow({ restaurant }:RestaurantRowProps) {
const [, cartStore] = useCartStore();
const handleClick = (food:Food) => () => {
cartStore.addCart(food);
};
return (
<tr>
<td>{restaurant.name}</td>
<td>
<ul>
{restaurant.menu.map((food) => (
<li role="presentation" key={food.id} onClick={handleClick(food)}> //✅ li요소에 role="presentation" 추가
<img src={food.image} alt={food.image} />
<p>{food.name}</p>
<p>{`${convertKRW(food.price)}원`}</p>
</li>
))}
</ul>
</td>
</tr>
);
}
export default RestaurantRow;
참조
'Frontend' 카테고리의 다른 글
[Sass] 다크 모드, 라이트 모드 구현하기 (1) | 2024.06.10 |
---|---|
[Storybook] 라이트모드, 다크모드 토글 기능 추가하기 (0) | 2024.06.10 |
[React] BrowserRouter vs HashRouter 비교 (0) | 2024.05.08 |
정규표현식에 변수값 사용하기 (0) | 2024.04.24 |
Box Model(박스 모델)이란? (0) | 2023.12.21 |