■ 내가 겪은 문제
게시판 형태의 페이지를 Next.js 14로 개발하던 중, 검색 기능을 구현하면서 이상한 문제를 만났다.
화면 구성은 다음과 같다:
- 왼쪽: 고정된 사이드바
- 상단: 헤더
- 중앙: 검색 필드와 결과 리스트가 있는 메인 영역
문제👉 검색어를 입력하고 검색 버튼을 누르면 전체 페이지가 새로고침된다.
사이드바, 헤더까지 전부 리셋되면서 React 상태도 초기화되어버린다.
처음엔 "React Query 캐시가 문제인가?" 싶었지만, 아니었다.
■ 원인 분석: form 태그의 기본 동작 때문
HTML에서 <form> 태그는 기본적으로 submit 이벤트 발생 시 페이지를 새로고침하고 서버로 데이터를 전송하는 구조를 가지고 있다. React에서도 <form>을 사용하면 이 기본 동작이 그대로 유지된다.
즉, onSubmit 이벤트가 발생해도 브라우저는 새로고침을 시도한다.
const handleSubmit = (e: React.FormEvent) => {
// e.preventDefault(); ← 이걸 안 썼을 때
refetch();
};
<form onSubmit={handleSubmit}>
<input type="text" />
<button type="submit">검색</button>
</form>
❗ 문제: e.preventDefault()가 없으면?
- 브라우저는 form을 전송하려고 페이지를 리로드함
- 그 결과 Next.js 앱 전체가 새로 로딩됨
- React Query, zustand, context, 모든 상태 초기화
- 결국 refetch()도 제대로 호출되지 않음 (초기값으로 다시 감)
■ 해결 방법: e.preventDefault() 추가
위 코드에서 e.preventDefault(); 코드 주석을 해제하고 사용하면 된다.
이렇게 하면:
- 페이지 전체가 새로고침되지 않고
- refetch()만 실행되어
- 메인 영역의 검색 결과만 깜빡이듯 갱신된다
왜 preventDefault()가 없으면 페이지 전체가 리로드될까?
HTML의 기본 form 동작 때문이며, React는 이걸 자동으로 막아주지 않는다.
SPA(Single Page Application)라도 <form>을 쓰면 **기본은 "submit → reload"**가 된다.
'React' 카테고리의 다른 글
Next.js 경로 끝 슬래시(/) (feat. 308 redirect) (0) | 2025.05.30 |
---|---|
[Next.js] 무료 에디터 Tiptap커스텀하기 (0) | 2025.03.26 |
[TypeScript] 제네릭을 활용한 setDto 최적화 - any 대신 T를 쓰는 이유 (0) | 2025.03.13 |
[Next.js] sessionStorage is not defined 오류 (0) | 2025.02.21 |
[Next.js vs React] 요청 흐름 차이 (0) | 2025.02.17 |