[React] onClick함수 자동실행, onClick undefined, React에서 이벤트 적용하기

keynene·2023년 7월 10일
0

React

목록 보기
21/21

React로 개발하다가 버튼 클릭 시 동작하는 기능을 구현하기 위해 onClick함수에 코딩을 했는데,
💻버튼 클릭하기도 전, 렌더링 시 함수가 2-3번 자동실행이 되고,
💻오히려 버튼 클릭 시 undefined또는 동작을 안 하는 경우가 있다.

알고보면 간단한 문제인데 실수를 반복하게 되어 정리하려고 한다.



1. onClick 함수에 함수 호출이 아닌, 함수를 "정의"하자.


<button onClick={alert('왜 동작안하냐')}> 보단 <button>

위 코드가 내가 짰던 코드인데, 코드를 실행해보면 버튼을 클릭하기도 전렌더링 시 "왜 동작안하냐" alert창이 여러 번 자동실행되고, 정작 버튼을 클릭했을 때는 아무 동작도 안하는 것이 문제였다.

결론부터 말하면 onClick함수 안의 alert기능이 클릭 했을 때의 이벤트동작이 아닌,
함수 호출로서 작동되어서 발생하는 문제였다.
정확히는 React의 구조 때문에 발생하는 문제였다.

사실 React는 렌더링 시 모든 컴포넌트의 함수를 실행시킨다.

그리고 React는 렌더링 하는 과정에서 함수나, useEffect함수 등으로 state에 변화가 생기면 또 렌더링 시켜버린다.
이 때문에 "왜 동작안하냐" alert창이 첫 렌더링 시 1번, state가 바뀔 때마다 계속 렌더링 시 N번 자동실행되고, 버튼을 누르면 더 이상 아무동작도 하지 않는 것이었다.

그러므로 이벤트함수는 렌더링 시 호출이 아니라 함수 "정의"해두고, 이벤트 발생 시 "호출"되게끔 코딩해야 한다는 것이다.

해결법은 간단하다.

1. arrowfunction

<button onClick={()=>{alert('정상작동😋')}}> 보단 </button>
현업에서도 가장 많이 쓰이는 방법이고, 가독성도 좋다.

2. 함수선언식

<button onClick={function() {alert('이것도 정상작동이긴 한데..🙁')}}> 보단 </button>
위 arrowfunction과 큰 차이는 없어보이나 지금과 같이 간단한 코드가 아닌, 함수 본문에서 this를 사용하게 된다면 문제가 될 수도 있으므로 arrowfunction방법을 좀 더 권장한다.




2. 문법을 제대로 적용했는가?


만약 1번과 같이 함수 정의를 했는데도 이상하게 동작한다면 초심으로 돌아갈 필요가 있다. React는 HTML/CSS/JavaScript 적어도 이 3가지 언어를 동시에 써야하기 때문에 충분히 헷갈릴 수 있다.

2-1. React의 이벤트는 카멜케이스를 사용한다.

DOM 엘리먼트는 이벤트 속성을 on+이벤트명으로 모두 소문자로 작성하지만,
React는 첫 단어 외 단어 시작점 알파벳을 대문자로 표현하는 카멜케이스로 작성해야 한다.

DOM : onclick, onmouseover, onsubmit
React : onClick, onMouseOver, onSubmit


2-2. React는 문자열이 아닌 함수로 이벤트 핸들러를 전달한다(JSX).

DOM 엘리먼트는 이벤트 핸들러 전달 시 문자열로 전달했지만,
React는 모두 JSX를 사용하여 인라인 형식으로 전달해야 한다.
(쉽게말해서, React는 {중괄호}안에 JS로 전달하면 된다는 뜻)

DOM : <button> 보단 </button>
React : <button onClick={()=>{함수명()}}> 보단 </button>


2-3. event.preventDefault 작업이 필요할 때도 있다.

만약 내 프로젝트가 버튼을 클릭할 때마다 새로고침되어서 state값이 다 날아가 버린다면,
이벤트의 기본 동작을 막아줄 필요가 있다.
대표적으로 onSubmit을 통해 데이터를 전송할 때 주로 사용된다.

DOM : 이벤트 핸들러가 false를 반환해도 해당 엘리먼트의 기본 동작을 방지할 수 있으므로 따로 기본 동작을 방지할 코드를 작성하지 않아도 된다.
React : 반드시 핸들러가 preventDefault를 호출해야 리로드 없이 정상작동 한다.

/*Test컴포넌트를 예로 들어보자*/
function Test(){
  function eventTest(e){
    e.preventDefault(); //해당 문구를 추가해야 새로고침을 방지할 수 있다.
    alert('이제 새로고침 없이 잘 돌아가지?');
  }
  
  return(
    <>
      <button onSubmit={()=>{eventTest()}}> 보단 </button>
	  //카멜, {중괄호}, preventDefault까지 완벽★
    </>
  
  )
}



📚정리

1. 이벤트 함수는 렌더링 시 실행되지 않도록 "정의" 👉🏻 arrowfucntion

arrowfunction : onClick={()=>{alert('이젠 그냥 외우자')}}
함수선언식 : onClick={function(){alert('비추! arrow 쓰자')}}

2. 문법 다시보자

2-1. 카멜케이스 : onclick X 👉🏻 onClick O
2-2. JSX : onClick="함수명()"X 👉🏻 onClick={()=>{함수명()}} O
2-3. 기본동작방지 : preventDefault();

profile
keynene

0개의 댓글