FE/React

[React] 이벤트가 두번 실행되는 오류 해결하기

Juliie 2021. 3. 16. 18:42
//SignupForm 오류 코드
 <div className="signup_box_button">
            <button onClick={alert("hi")}>
             회원 가입
            </button>

회원가입 폼을 만들고 있던 중 button의 이벤트가 두 번으로 중복돼서 실행되는 오류가 생겼다

열심히 구글링해서 찾아낸 결과 이유는

 

1) React.StrictMode (실질적인 해결방법은 아니였지만...ㅎ)

//index.js
ReactDOM.render(
  <React.StrictMode>
    <App />,
  </React.StrictMode>,
  document.getElementById("root")
);

리액트의 공식 문서를 살펴보면

Strict 모드
StrictMode는 애플리케이션 내의 잠재적인 문제를 알아내기 위한 도구입니다.

! Strict 모드는 개발 모드에서만 활성화되기 때문에, 프로덕션 빌드에는 영향을 끼치지 않습니다.

* 안전하지 않은 생명주기를 사용하는 컴포넌트 발견
* 레거시 문자열 ref 사용에 대한 경고
* 권장되지 않는 findDOMNode 사용에 대한 경고
* 예상치 못한 부작용 검사
* 레거시 context API 검사
위의 메서드들은 여러 번 호출될 수 있기 때문에, 부작용을 포함하지 않는 것이 중요합니다. 이 규칙을 무시할 경우, 메모리 누수 혹은 잘못된 애플리케이션 상태 등 다양한 문제를 일으킬 가능성이 있습니다. 불행히도, 보통 이러한 문제들은 예측한 대로 동작하지 않기 때문에 발견하는 것이 어려울 수 있습니다. Strict 모드가 자동으로 부작용을 찾아주는 것은 불가능합니다. 하지만, 조금 더 예측할 수 있게끔 만들어서 문제가 되는 부분을 발견할 수 있게 도와줍니다.

이는 아래의 함수를 의도적으로 이중으로 호출하여 찾을 수 있습니다.
* 클래스 컴포넌트의 constructor, render 그리고 shouldComponentUpdate 메서드
* 클래스 컴포넌트의 getDerivedStateFromProps static 메서드
* 함수 컴포넌트 바디 * State updater 함수 (setState의 첫 번째 인자)
* useState, useMemo 그리고 useReducer에 전달되는 함수 개발 모드에서만 적용됩니다.

!생명주기 메서드들은 프로덕션 모드에서 이중으로 호출되지 않습니다.

요약하자면 나의 경우는 StrictMode가 클래스 컴포넌트의 render 함수를 일부러 2번 실행해서 함수 또한 두번 실행됐다는 것!

그래서 StrictMode 코드만 지워주면 될 줄 알았는데 본질적인 이유는 따로 있었다

 

2) onClick 이벤트에 함수를 전달하는 대신 바로 호출했기 때문에 

리액트의 onclick 렌더링때 실행된다

<button id="btn" onClick={alert("hi")} /> //렌더링 될때 (버튼 클릭 전) 이벤트 발생
<button id="btn" onClick={() => alert("hi")} /> //정상적으로 버튼을 클릭할 때 이벤트 발생

ko.reactjs.org/docs/handling-events.html

 

이벤트 처리하기 – React

A JavaScript library for building user interfaces

ko.reactjs.org

리액트 공식문서에 나와있는데 이걸 몰랐네...🥲

하지만 공식 문서는 저 방법 대신 생성자 안에서 바인딩하거나 클래스 필드 문법을 사용하는 것을 권장한다

이 부분은 더 공부하고 추가하는걸로 ꉂꉂ(ᵔᗜᵔ*)