2024-08-21 광클을 방지하기 위한 노력
상황
하트를 누르면 팔로우가 되는 버튼을 만들었다.
보기엔 간단해보여도
자신에게 팔로우 요청을 보내는 것인지,
이미 팔로우가 되어 있진 않은지,
팔로우를 하려는 건지, 언팔로우를 하려는 건지
로그인이 되어 있는지,
상대방이 탈퇴한 회원은 아닌지 등
굉장히 많은 비용이 발생하는 버튼이다.
그런데 기능 구현을 하고 나니, 뿌듯한 마음에 네트워크 탭을 열고
계속 눌렀다 떼었다를 반복했다.
그러면서 문득 든 생각.
"사용자도 멍 때리면서 계속 누르기 딱 좋게 생겼는데?"
나의 서버비를 아끼기 위해 광클을 막아야겠다고 결심한 순간이다.
한계
나의 구현 방식에는 한계가 있다.
카드 하나의 버튼을 광클하지 못하게 하는 것이고, 저런 카드가 수백장 있다고 했을 때
매크로가 카드 엘리먼트를 찾아서 계속 클릭하는 것은 이 로직으로 막지 못한다.
어차피 본인의 경우에는 카드가 최대 10개밖에 렌더링 되지 않기 때문에
그런 봇이 있을 리가 없을 것이고... 따라서 거기 까지 막을 이유는 없어서 구현하진 않았지만,
추후 생각해볼 만한 과제인 것 같다.
광클 막기
경고창으로 광클 막기
// 상태 만들기
const [clickCount, setClickCount] = useState<number>(0);
const [clickTimeout, setClickTimeout] = useState<NodeJS.Timeout | null>(null,);
// 아래 로직들은클릭했을 때의 이벤트 함수 안에 넣어야 한다.
// 클릭 횟수 증가 시키기
setClickCount(prev => prev + 1);
// 타이머 설정하기
if (clickTimeout) clearTimeout(clickTimeout);
setClickTimeout(setTimeout(() => setClickCount(0), 5000));
// 5번 연속 클릭하면 경고창 띄우기
if (clickCount >= 4) {
showAlert('caution', '너무 많이 클릭했습니다! 잠시 후 다시 시도해주세요.',);
setClickCount(0); // 카운트 초기화
}
알고리즘을 살펴보자.
먼저 clickCount라는 상태를 만들어서 사용자의 하트 버튼 클릭 횟수를 카운팅한다.
그런데 그냥 막 하는 것은 아니고,
타이머를 5초로 설정해두고, 5초 안에 다시 클릭을 하지 않으면 clickCount를 0으로 초기화 시킨다.
그러나 5초 내에 다시 클릭하면 카운트는 증가된다.
그렇게 카운트가 증가하다가 clickCount가 4가 되는 순간, 즉 첫 클릭을 포함해서 총 5번을 클릭하는 순간
경고창을 띄운다.
한계는 있다. 경고창이 뜨면 return키로 경고창을 닫고 또 매크로를 돌리면 된다.
클릭 이벤트에 setTimeout 속성을 주어 버튼 자체를 disabled 시키기
가장 많이 사용되는 방법이 아닐까 생각된다.
광클을 방지할 수 있고, 글쓰기의 경우 따닥으로 인한 중복 제출을 방지할 수도 있다.
이 불리언 값이 true가 되면 disabled 속성이 true로 토글되어 버튼 자체의 클릭이 막히는 로직이다.
다만 여기에 시간을 걸 뿐이다.
// 상태 만들기
const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(false);
// 버튼에 연결할 이벤트 함수를 시작하자마자 true로 토글
const handleFollowToggle = async (
e: React.MouseEvent<HTMLButtonElement>,
) => {
onClick(e);
setIsButtonDisabled(true);
// 이하 생략 ...
// 2초 뒤에 false로 토글하기
setTimeout(() => {setIsButtonDisabled(false);}, 2000);
// 버튼에 disabled 속성 부여하기
<button
className="absolute top-0 right-0 text-xl mr-1 mt-1"
onClick={handleFollowToggle}
disabled={isButtonDisabled}
>
<span className={isFollowing ? 'text-main-color' : ''}>
{isFollowing ? '♥' : '♡'}
</span>
</button>
끝.
'Programing > TIL' 카테고리의 다른 글
2024-08-23 TanStackQuery enabled 옵션으로 페칭 순서 조정하기 (0) | 2024.08.23 |
---|---|
2024-08-22 컴포넌트 재사용에 따른 조건부 로직 구현 방법 (0) | 2024.08.22 |
2024-08-20 이벤트 전파(event bubbling) (0) | 2024.08.20 |
2024-08-19 [Next.js, Supabase] 여러 테이블을 참조하는 DELETE 메서드 작성하기 (0) | 2024.08.19 |
2024-08-16 미인증 사용자에게는 블러 처리된 오버레이 모달 렌더링하기 (0) | 2024.08.16 |
댓글