본문 바로가기
웹 개발/소소한 팁, 버그 해결

[Next.js 14] 버튼 동시에 눌리는 현상 막기 [stopPropagation][Typescript]

by 마라턍 2024. 3. 20.

웹을 디자인하다 보면 어떤 정보를 담고 있는 버튼 안에 삭제 버튼이 있는 것처럼 버튼과 버튼이 겹치는 것이 불가피할 때가 있다.

이때 눌러보면 두 버튼이 모두 작동하는데, 버튼을 눌렀을 때 하나만 동작하는 것이 일반적이니 이를 어떻게 할 수 있을지 알아보자.

 

핵심은 event의 stopPropagation()이다. 안에 있는 버튼에 아래와 같이 선언해주면 안쪽 버튼이 눌릴 때 바깥쪽 버튼이 안 눌리는 것을 확인할 수 있다.

    const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
        e.stopPropagation();
        // Do something
    }

 

아래는 이를 활용한 예시 코드이다.

import "@/styles/components/card.css";
import React from 'react';
import {CreditCardProp} from "@/types/creditCard";
import ButtonIcon from '@/components/button/ButtonIcon';
import ImageButton from '@/components/button/ImageButton';

const CardComponent = ({card, onSelect, focused, selected, canDelete}:CreditCardProp) => {
    const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
        e.stopPropagation();
        // Do something
    }
    
    return (
        <>
            <button className={`card ${focused && "focused"}`} onClick={focused ? () => onSelect() : undefined}>
                <div className="card-info">
                    <p className="card-name">{card.name}</p>
                    <div className="card-info--details">
                        <p className="card-exp-date">{card.cardExpirationMonth}/{card.cardExpirationYear} 만료</p>
                        <p className="card-number">****-****-****-{card.cardNumber.slice(-4)}</p>
                    </div>
                </div>
                {
                    !canDelete &&
                    <div className="additional-button">
                        <ImageButton icon={'delete-bin'} onClick={onClick} type={'line'} />
					</div>
            	}
            	{
                    <div className={`select-icon ${selected && 'selected'}`}>
                        <ButtonIcon name="checkbox-circle" type="line" size="xl" />
                    </div>
                }
            </button>
        </>
    )
}

export default CardComponent

뭐가 많긴 하지만 암튼 이런 식으로 쓰이니 참고하세용...

 

이번에는 버튼 클릭 이벤트로 예시를 들었지만, 어쨌든 Event 타입이므로 이를 마우스 스크롤 이벤트나 키보드 이벤트로 확장해서 활용할 수 있다.

 

더 자세한 내용은 Documentation 참고.

 

Event.stopPropagation() - Web API | MDN

Event 인터페이스의 stopPropagation() 메서드는 현재 이벤트가 캡처링/버블링 단계에서 더 이상 전파되지 않도록 방지합니다. 전파를 방지해도 이벤트의 기본 동작은 실행되므로, stopPropagation()이 링

developer.mozilla.org

 

 

Event - Web API | MDN

Event 인터페이스는 DOM에서 발생하는 이벤트를 나타냅니다.

developer.mozilla.org

끗~