티스토리 뷰

반응형

SvelteKit으로 시작하는 SSR 백엔드-프론트 기초 100단계

3단계 — use:enhance로 SSR 폼을 새로고침 없이 동작하게 만들기

(서버는 그대로, UX만 SPA처럼 — 점진적 향상 제대로 이해하기)

2단계에서 우리는 아무 JS 없이도 서버에 POST를 보내고(actions),
서버에서 검증/처리한 결과를 SSR로 다시 렌더하는 걸 봤습니다.

이번 단계는 여기서 한 발 더 갑니다.

서버 구조는 그대로 유지하면서
페이지 새로고침만 없애자

이걸 가능하게 해주는 게 use:enhance 입니다.


3단계 목표

  • use:enhance가 무엇을 바꾸고, 무엇을 바꾸지 않는지 이해한다
  • 새로고침 없는 폼 제출을 구현한다
  • 성공/실패 결과를 즉시 UI에 반영한다
  • “SSR + SPA UX”라는 말을 몸으로 이해한다

먼저, 핵심 개념부터 정리 (이거 중요)

❌ 흔한 오해

“use:enhance 쓰면 SPA 되는 거 아니에요?”

✅ 정확한 이해

  • 서버는 여전히 actions
  • HTML 폼도 그대로
  • 단지 브라우저가 form submit을 가로채서(fetch로) 처리해줄 뿐

즉,

JS OFF  → 2단계와 동일하게 동작
JS ON   → 새로고침 없이 서버 action 호출

이게 점진적 향상(Progressive Enhancement) 입니다.


Step 3-1. 지금 코드 상태 점검

2단계 기준으로, 우리는 이런 구조를 가지고 있어야 합니다.

  • src/routes/+page.svelte
  • src/routes/+page.server.ts
  • <form method="POST">
  • actions.default

👉 서버 코드는 오늘 수정 안 합니다.


Step 3-2. use:enhance 붙이기 (딱 한 줄)

반응형

1️⃣ enhance import

src/routes/+page.svelte

<script lang="ts">
	import { enhance } from '$app/forms';

	export let data: {
		serverTime: string;
		message: string;
		error?: string;
		success?: boolean;
	};
</script>

2️⃣ form에 use:enhance 추가

<form method="POST" use:enhance>
	<input
		type="text"
		name="title"
		placeholder="아무 글이나 입력해보세요"
	/>
	<button type="submit">서버로 전송</button>
</form>

⚠️ 이거 말고 아무것도 안 바꿨습니다.


Step 3-3. 지금 무슨 일이 벌어졌나?

이제 브라우저에서 테스트해보세요.

✅ 동작 변화

  • 페이지 새로고침 안 됨
  • URL 그대로
  • 서버 actions는 여전히 호출됨
  • 성공/실패 메시지는 즉시 반영

❌ 변하지 않은 것

  • 서버 로직
  • validation
  • HTTP 요청/응답 개념

👉 서버는 몰라요.
👉 “아, 이 폼이 SPA처럼 동작하네?”는 브라우저의 선택입니다.


Step 3-4. 로딩/결과를 더 명확히 보여주기

이제 UX를 조금만 다듬어봅시다.
use:enhance는 콜백을 받을 수 있습니다.

enhance 콜백 기본 형태

<form
	method="POST"
	use:enhance={({ pending, result }) => {
		// pending: 요청 중
		// result: 서버 응답
	}}
>

실제 적용 예시 (실행 가능)

<script lang="ts">
	import { enhance } from '$app/forms';

	let loading = false;

	export let data: {
		serverTime: string;
		message: string;
		error?: string;
		success?: boolean;
	};
</script>

<h1>Step 3: use:enhance</h1>

<p>{data.message}</p>
<p>Server time: {data.serverTime}</p>

<form
	method="POST"
	use:enhance={() => {
		loading = true;

		return async ({ result }) => {
			loading = false;

			// 서버 action 결과 확인
			if (result.type === 'failure') {
				console.log('서버 validation 실패');
			}

			if (result.type === 'success') {
				console.log('서버 처리 성공');
			}
		};
	}}
>
	<input
		type="text"
		name="title"
		placeholder="아무 글이나 입력해보세요"
	/>
	<button type="submit" disabled={loading}>
		{loading ? '전송 중...' : '서버로 전송'}
	</button>
</form>

{#if data.error}
	<p style="color: red">{data.error}</p>
{/if}

{#if data.success}
	<p style="color: green">서버에서 정상 처리되었습니다!</p>
{/if}

Step 3-5. 주니어가 꼭 이해해야 할 result.type

result.type은 3가지 중 하나입니다.

type의미

success action이 정상 return
failure fail()로 반환
error 서버 에러 (throw 등)

👉 이걸로 토스트, 로그, 애널리틱스 분기를 합니다.


Step 3-6. 이 구조가 왜 “실무 친화적”인가

1️⃣ 서버 우선 사고

  • 모든 비즈니스 로직은 서버
  • 프론트는 표현/UX만 담당

2️⃣ 점진적 향상

  • JS 꺼져도 OK
  • 네트워크 느려도 OK
  • 접근성 기본 확보

3️⃣ 나중에 커져도 안 흔들림

  • fetch 난무 ❌
  • API 중복 ❌
  • 상태관리 지옥 ❌

자주 하는 실수 TOP 3

❌ use:enhance 쓰면 load가 안 도는 줄 앎

  • 돌아요
  • action 이후 load 재실행이 기본입니다

❌ enhance 안에서 모든 상태를 관리하려 함

  • 기본은 SSR 데이터(data)
  • enhance는 UX 보조용

❌ 이걸 React Form 대용으로만 생각함

  • 핵심은 서버 중심 설계
  • SPA 흉내가 목적이 아님

오늘 단계에서 꼭 가져가야 할 감각

“서버는 그대로 두고
UX만 점진적으로 개선할 수 있다”

이 감각이 잡히면
SSR이 낡은 게 아니라, 오히려 단단하다는 것이 보입니다.


 

SvelteKit,SSR,useEnhance,FormActions,점진적향상,주니어개발자,백엔드기초,프론트엔드,풀스택,웹개발

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함
반응형