2026. 7. 16.

React 버튼을 누르면 페이지가 새로고침될 때, type과 submit부터 확인하세요

React 폼 안의 버튼을 눌렀더니 페이지가 다시 로드되고 입력값이 사라진다면, button type과 form submit을 나눠 확인하고 URL·Network·입력 상태로 수정 결과를 검증하는 순서다.

3 min read
React 버튼을 누르면 페이지가 새로고침될 때, type과 submit부터 확인하세요 대표 이미지

React 입력 폼에서 버튼을 눌렀더니 결과가 잠깐 보인 뒤 화면이 다시 로드되고 입력값이 사라질 수 있다. onClick이나 state가 틀렸다고 보고 handler만 다시 고치기 쉽지만, 먼저 볼 곳은 **버튼을 감싼 formbuttontype**이다.

판단은 두 갈래다. 제출하지 않는 버튼이면 type="button"을 명시한다. 실제로 데이터를 제출하는 버튼이면 type="submit"을 명시하고 제출 로직을 form onSubmit에서 처리한다. 브라우저의 기본 페이지 이동을 원하지 않는 경우에만 그 submit event에서 preventDefault()를 호출한다.

React 폼 안의 버튼이 일반 동작과 실제 제출로 갈라지는 확인 흐름

먼저 버튼의 의도를 두 갈래로 나눕니다

MDN의 <button> 문서에 따르면 form과 연결된 buttontype을 생략하면 기본적으로 submit 버튼이 된다. React 컴포넌트 안에 <button onClick={...}>만 썼더라도 이 HTML 동작은 남는다. click handler가 실행된 직후 form 제출이 이어지면 브라우저가 현재 URL로 이동하고 화면 상태가 초기화될 수 있다.

문제 버튼을 찾으면 다음 두 질문만 적는다.

  1. 이 버튼은 폼 데이터를 서버나 submit handler로 보내야 하는가?
  2. 아니면 모달 열기, 항목 추가, 비밀번호 표시처럼 화면 안의 동작만 해야 하는가?

두 번째라면 submit 자체가 원인이 될 가능성이 크다. 특히 공용 Button 컴포넌트가 실제 <button>을 반환하면서 type을 전달하지 않으면, 폼 밖에서는 멀쩡하고 폼 안에서만 새로고침되는 증상이 나타난다. 공용 컴포넌트가 의심된다면 커스텀 Button의 prop 전달 두 곳을 확인하는 글도 함께 보면 수정 범위를 좁힐 수 있다.

일반 버튼은 type, 제출 버튼은 form onSubmit에서 고칩니다

제출하지 않는 버튼은 type을 명시합니다

항목 추가나 도움말 열기처럼 폼을 제출하지 않는 동작은 type="button"으로 고친다. 이 한 줄은 브라우저에 “이 버튼에는 submit 기본 동작이 없다”고 알려준다.

<form>
  <input value={name} onChange={(e) => setName(e.target.value)} />
  <button type="button" onClick={addPreview}>
    미리보기 추가
  </button>
</form>

공용 컴포넌트라면 type을 prop으로 받아 실제 DOM button까지 전달한다. 다만 공용 버튼의 기본값을 무조건 button으로 바꾸면 기존 제출 버튼이 멈출 수 있다. 사용처를 확인하고 제출 버튼에는 type="submit"을 명시한다.

실제 제출은 form의 onSubmit에서 처리합니다

저장·로그인·검색처럼 Enter 키로도 실행돼야 하는 제출은 click handler보다 form의 onSubmit에 둔다. 클라이언트 상태만 갱신하고 현재 페이지를 유지하려면 submit event의 기본 동작을 막는다.

function ProfileForm() {
  const [name, setName] = useState("");

  function handleSubmit(event) {
    event.preventDefault();
    saveProfile(name);
  }

  return (
    <form onSubmit={handleSubmit}>
      <input value={name} onChange={(event) => setName(event.target.value)} />
      <button type="submit">저장</button>
    </form>
  );
}

이 구조는 버튼 클릭과 Enter 제출을 한 경로로 모은다. preventDefault()는 제출 로직 자체를 취소하는 명령이 아니라 브라우저가 기본으로 수행할 페이지 이동을 막는 명령이다.

함수형 action은 같은 규칙으로 덮지 않습니다

React의 <form action={someFunction}>이나 Server Function을 의도해 쓴 경우에는 onSubmit 방식과 경계가 다르다. React의 <form> 공식 문서는 함수형 action이 Transition에서 실행되며 preventDefault()가 필요하지 않다고 설명한다. 성공 뒤 uncontrolled 입력이 초기화되는 것도 정상 동작일 수 있다. 페이지 전체가 다시 로드된 것인지, action 성공 뒤 필드만 reset된 것인지 먼저 구분해야 한다.

URL·Network·입력값 세 곳으로 수정 결과를 확인합니다

React 버튼 수정 전후를 URL과 Network 요청, 입력값 유지 상태로 비교하는 체크리스트

코드 한 줄을 바꿨다고 끝내지 않는다. 같은 입력과 같은 버튼으로 전후를 비교한다.

  • URL: 버튼 클릭 뒤 주소나 query string이 의도 없이 바뀌지 않는가.
  • Network: 개발자 도구에 새 document 요청이 생기지 않는가. 의도한 API 요청만 남는가.
  • 입력값: 입력 중인 값과 방금 만든 미리보기·메시지가 클릭 뒤에도 유지되는가.

테스트할 때는 먼저 입력창에 식별하기 쉬운 문구를 넣고 Network 기록을 비운다. 문제 버튼을 한 번 누른 뒤 세 곳을 기록한다. 수정 후 같은 순서로 다시 눌러 document 요청이 사라지고 의도한 상태만 남는지 확인한다. select 값 자체가 바뀌지 않는 문제라면 submit과 다른 원인일 수 있으므로 React select의 value와 onChange 점검 순서로 분리한다.

stopPropagation은 이 새로고침을 막는 도구가 아닙니다

stopPropagation()은 클릭 이벤트가 부모 요소의 handler로 올라가는 것을 막는다. form submit이라는 브라우저 기본 동작을 없애지는 않는다. 상위 click handler가 두 번 실행되는 문제와 페이지가 다시 로드되는 문제를 같은 것으로 보면 수정이 겉돈다.

또한 모든 form 제출을 막아서는 안 된다. 검색 URL로 이동하거나 React action을 실행하는 것이 목표라면 submit은 정상 동작이다. 일반 버튼인지 실제 제출인지 먼저 정하고, 한 갈래만 수정한다. 그 뒤 URL·Network·입력값이 의도한 상태인지 확인하면 이 문제는 재현 가능한 테스트로 닫을 수 있다.

참고 출처

이 글은 AI 코딩과 개발 학습의 일반 정보 제공 목적입니다. 도구, 모델, 커리큘럼, 요금은 버전과 시점에 따라 달라질 수 있으므로 실습이나 도입 전 공식 문서와 최신 릴리스 노트를 확인하세요.

다음으로 읽을 기사

같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.

댓글 0

이 글을 읽은 독자들의 생각을 나눠보세요.

비밀번호(선택)

첫 번째 댓글을 남겨보세요

여러분의 생각이 다른 독자에게 도움이 됩니다.