엥? Form 안의 버튼 눌렀는데 왜 새로고침이...? 🤯

홍태극·2023년 8월 17일
0

엥? Form 안의 버튼 눌렀는데 왜 새로고침이...? 🤯

개발하다 보면 정말 예상치 못한 문제들을 만나곤 하죠? 저도 어느 날 평화롭게 React로 웹 개발을 하고 있었어요. <form> 태그 안에 버튼(button)을 하나 넣어서 사용하고 있었는데요. 🕊️

그런데! 이 버튼을 누를 때마다 페이지 전체가 새로고침되는 것처럼 보이는 현상이 발생하는 거예요! "어? 왜 이러지?" 싶어서 컴포넌트 상태(state)나 속성(props) 문제인가 싶어 구글링도 해보고 ChatGPT한테도 물어봤죠. 근데 자꾸 엉뚱하게 상위 컴포넌트가 어떻다느니, Redux가 문제라느니... 제가 겪는 문제랑은 전혀 상관없는 답변만 돌아오더라고요. 답답해 미치는 줄 알았어요! 😫

🤔 뭐가 문제였을까요? (문제 분석 타임!)

"도대체 뭐가 문제지?" 하고 코드를 한참 들여다봤어요. 그러다 문득 <form> 태그 안에 덩그러니 놓여있는 <button> 태그가 눈에 확 들어오는 거예요! 👀

"혹시... 이거 때문인가?"

네, 바로 그거였어요! HTML의 기본 동작 방식 때문이었죠. <form> 태그 안에 있는 <button> 요소는 우리가 타입을 특별히 지정해주지 않으면, 브라우저가 기본적으로 type="submit"으로 인식해요. 즉, 이 버튼을 누르면 자기도 모르게 폼(form)을 제출(submit)하려고 했던 거예요! 폼이 제출되면 페이지가 새로고침되는 게 기본 동작이니, 제가 봤던 현상이 바로 이것 때문이었던 거죠. 아하!💡

✨ 해결 방법은 생각보다 간단해요!

원인을 알고 나니 해결책은 아주 쉬웠어요. 버튼이 기본적으로 폼을 제출하는 행동을 막아주면 되는 거였죠! 방법은 크게 두 가지가 있어요.

방법 1 - event.preventDefault() 사용하기

폼 제출 이벤트나 버튼 클릭 이벤트 핸들러 함수 안에서 event.preventDefault() 메서드를 호출해주는 거예요. 이건 브라우저에게 "이봐, 원래 하려던 기본 동작(여기서는 폼 제출)은 잠깐 멈춰줘!" 라고 말하는 것과 같아요.

방법 2 - 버튼에 type="button" 명시하기

<button> 태그에 아예 type="button" 속성을 직접 딱! 명시해주는 거예요. 이렇게 하면 브라우저에게 "얘는 폼 제출하는 애 아니고, 그냥 평범한 버튼이야!" 라고 확실하게 알려주는 거죠.

둘 중 편한 방법 하나만 사용해도 페이지가 새로고침되는 현상을 막을 수 있답니다! 😉

💻 예제 코드로 확인해볼까요?

아래는 <form> 태그 안의 버튼이 새로고침되는 것을 막는 두 가지 방법을 모두 적용한 예제 코드예요. 실제 코드에서는 둘 중 하나만 쓰셔도 충분해요!

import React from 'react';

function MyForm() {
  // 폼 제출 이벤트 핸들러
  function handleSubmit(event) {
    // 방법 1: 폼의 기본 제출 동작을 막아요!
    event.preventDefault();

    // 여기에 폼 제출 시 처리할 로직을 작성해요 (예: API 호출 등)
    console.log('폼 제출 로직 실행! (새로고침 안됨)');
  }

  return (
    // form 태그에 onSubmit 이벤트 핸들러를 연결해요.
    <form onSubmit={handleSubmit}>
      {/* 여기에 폼 입력 필드들이 들어갈 수 있겠죠? */}
      <input type="text" placeholder="이름을 입력하세요" />

      {/* 방법 2: 버튼 타입을 'button'으로 명시해요! */}
      {/* 이렇게 하면 이 버튼 자체는 폼 제출을 유발하지 않아요. */}
      {/* 하지만 보통은 폼 제출용 버튼은 type="submit"으로 두고 */}
      {/* onSubmit 핸들러에서 preventDefault()를 쓰는 경우가 더 많아요. */}
      {/* 만약 폼 제출과 관련 없는 그냥 버튼이라면 type="button"이 좋겠죠? */}
      <button type="button" onClick={() => console.log('일반 버튼 클릭!')}>
        이건 그냥 일반 버튼
      </button>

      {/* 폼 제출을 위한 버튼 (type="submit"이 기본값이지만 명시해도 좋아요) */}
      <button type="submit">제출하기 (클릭 시 handleSubmit 실행)
      </button>
    </form>
  );
}

export default MyForm;

이 코드에서 "폼 제출하기" 버튼을 누르면 handleSubmit 함수가 실행되고, 함수 맨 위에서 event.preventDefault()를 호출했기 때문에 페이지 새로고침 없이 콘솔에 메시지만 찍힐 거예요! "이건 그냥 일반 버튼"은 type="button"으로 지정했으니 당연히 폼 제출과 상관없이 자기 onClick 로직만 실행하고요.

핵심 요약!
<form> 안에 버튼을 쓸 때는 얘가 혹시 자기도 모르게 폼을 제출하려고 하지는 않는지 꼭 한번 확인해보세요! 그리고 필요하다면 event.preventDefault()type="button"으로 기본 동작을 막아주는 센스! 잊지 마세요 😉

1개의 댓글

comment-user-thumbnail
2023년 8월 17일

훌륭한 글 감사드립니다.

답글 달기