React로 개발하다가 버튼 클릭 시 동작하는 기능을 구현하기 위해 onClick
함수에 코딩을 했는데,
💻버튼 클릭하기도 전, 렌더링 시 함수가 2-3번 자동실행이 되고,
💻오히려 버튼 클릭 시 undefined
또는 동작을 안 하는 경우가 있다.
알고보면 간단한 문제인데 실수를 반복하게 되어 정리하려고 한다.
<button onClick={alert('왜 동작안하냐')}> 보단 <button>
위 코드가 내가 짰던 코드인데, 코드를 실행해보면 버튼을 클릭하기도 전인 렌더링 시 "왜 동작안하냐" alert
창이 여러 번 자동실행되고, 정작 버튼을 클릭했을 때는 아무 동작도 안하는 것이 문제였다.
결론부터 말하면 onClick
함수 안의 alert
기능이 클릭 했을 때의 이벤트동작이 아닌,
함수 호출로서 작동되어서 발생하는 문제였다.
정확히는 React의 구조 때문에 발생하는 문제였다.
그리고 React는 렌더링 하는 과정에서 함수나, useEffect
함수 등으로 state
에 변화가 생기면 또 렌더링 시켜버린다.
이 때문에 "왜 동작안하냐" alert
창이 첫 렌더링 시 1번, state가 바뀔 때마다 계속 렌더링 시 N번 자동실행되고, 버튼을 누르면 더 이상 아무동작도 하지 않는 것이었다.
해결법은 간단하다.
<button onClick={()=>{alert('정상작동😋')}}> 보단 </button>
현업에서도 가장 많이 쓰이는 방법이고, 가독성도 좋다.
<button onClick={function() {alert('이것도 정상작동이긴 한데..🙁')}}> 보단 </button>
위 arrowfunction과 큰 차이는 없어보이나 지금과 같이 간단한 코드가 아닌, 함수 본문에서 this
를 사용하게 된다면 문제가 될 수도 있으므로 arrowfunction방법을 좀 더 권장한다.
DOM 엘리먼트는 이벤트 속성을 on+이벤트명으로 모두 소문자로 작성하지만,
React는 첫 단어 외 단어 시작점 알파벳을 대문자로 표현하는 카멜케이스로 작성해야 한다.
DOM : onclick, onmouseover, onsubmit
React : onClick, onMouseOver, onSubmit
DOM 엘리먼트는 이벤트 핸들러 전달 시 문자열로 전달했지만,
React는 모두 JSX를 사용하여 인라인 형식으로 전달해야 한다.
(쉽게말해서, React는 {중괄호}안에 JS로 전달하면 된다는 뜻)
DOM : <button> 보단 </button>
React : <button onClick={()=>{함수명()}}> 보단 </button>
만약 내 프로젝트가 버튼을 클릭할 때마다 새로고침되어서 state값이 다 날아가 버린다면,
이벤트의 기본 동작을 막아줄 필요가 있다.
대표적으로 onSubmit
을 통해 데이터를 전송할 때 주로 사용된다.
DOM : 이벤트 핸들러가 false
를 반환해도 해당 엘리먼트의 기본 동작을 방지할 수 있으므로 따로 기본 동작을 방지할 코드를 작성하지 않아도 된다.
React : 반드시 핸들러가 preventDefault를 호출해야 리로드 없이 정상작동 한다.
/*Test컴포넌트를 예로 들어보자*/
function Test(){
function eventTest(e){
e.preventDefault(); //해당 문구를 추가해야 새로고침을 방지할 수 있다.
alert('이제 새로고침 없이 잘 돌아가지?');
}
return(
<>
<button onSubmit={()=>{eventTest()}}> 보단 </button>
//카멜, {중괄호}, preventDefault까지 완벽★
</>
)
}
arrowfunction : onClick={()=>{alert('이젠 그냥 외우자')}}
함수선언식 : onClick={function(){alert('비추! arrow 쓰자')}}
2-1. 카멜케이스 : onclick
X 👉🏻 onClick
O
2-2. JSX : onClick="함수명()"
X 👉🏻 onClick={()=>{함수명()}}
O
2-3. 기본동작방지 : preventDefault();