yceffort / yceffort-blog-v2

yceffort.kr
https://yceffort.kr/
85 stars 7 forks source link

[Discussion] issue on (함수형으로) 자바스크립트로 HTML 버튼 중복 클릭 방지하기 #598

Closed opp1350 closed 1 year ago

opp1350 commented 1 year ago

https://yceffort.kr/2020/10/prevent-double-click-on-button

안녕하세요, 먼저 좋은 글 감사합니다. :) 어떻게 이 문제를 해결해야할지 고민 중에 yceffort님 블로그 글을 보게 되었습니다. 내용대로 적용해 보다가 아래의 doOnce 함수에 대해 궁금한 점이 생겨서 글 남겨봅니다. (제 이해의 부족이라면 미리 죄송합니다)

const doOnce = (fn) => {
  let done = false
  return (...args) => {
    if (!done) {
      done = true
      fn(...args)
    }
  }
}

버튼을 연속으로 클릭할 때마다 doOnce 함수가 실행되면, 그때마다 함수 내부에 있는 done은 새로 선언될텐데 done이 true(인자로 받은 원본 함수가 실행 중인 상태)인지 어떻게 알 수 있나요? 동일하게 적용해보았는데, 연속 클릭이 막아지지 않습니다. :sob:

yceffort commented 1 year ago

@opp1350 님, 안녕하세요?

제가 설명이 부족했던 것 같습니다. doOnce는 말씀하신대로 고차함수이기 때문에, 실행할때마다 호출되면 done이 계속 초기화 되기 때문에 동작하지 않습니다. 따라서 다음과 같이 작성해야 올바르게 동작합니다.

const doOnce = (fn) => {
  let done = false;
  return (...args) => {
    if (!done) {
      done = true;
      fn(...args);
    }
  };
};

export default function App() {
  const handleClick = doOnce(() => {
    alert("반갑습니다.");
  });

  return (
    <div className="App">
      <button onClick={handleClick}>안녕하세요</button>
    </div>
  );
}

이 경우에도, 마찬가지로 App이 모종의 이유로 리렌더링된다면 다시금 handleClick이 실행가능한 상태가 될 것입니다.

작성하신 코드가 어떤 상태인지 알 수 없지만, 리렌더링이 되지 않고 doOnce를 올바르게 쓰신다면 함수 실행을 원하는 대로 한번으로 제한할 수 있을 것으로 기대됩니다.

감사합니다.

opp1350 commented 1 year ago

yceffort님, 올려주신대로 적용해보니 클릭 이벤트가 한번으로 제한되네요.

자세한 답변 감사합니다! 많은 도움이 되었습니다... :man-bowing:

yceffort commented 1 year ago

@opp1350 도움이 되셨다면 다행입니다 🙇‍♂️ 혹시나 궁금한점 생기면 언제든 문의 주세요. 감사합니다 :) 날씨 추운데 감기조심하세요!