본문으로 건너뛰기

초안: 폼에서 검색 매개변수 처리

최종 목적지: docs/router/framework/react/how-to/search-params-in-forms.md
점진적 시리즈 위치: 전문 사용 사례 - 가이드 #10
종속 항목: setup-basic-search-params.md, navigate-with-search-params.md, validate-search-params.md
상태: 구현 준비 완료 - 폼 동기화 패턴 사용 가능


navigate-with-search-params.md에서 스테이징된 콘텐츠

컴포넌트 상태를 URL 검색 매개변수와 동기화합니다.

import { useState, useEffect } from 'react'
import { useNavigate, useSearch } from '@tanstack/react-router'

function SynchronizedForm() {
const navigate = useNavigate()
const search = useSearch({ from: '/products' })

// Local state synced with URL
const [localFilters, setLocalFilters] = useState({
minPrice: search.minPrice || 0,
maxPrice: search.maxPrice || 1000,
inStock: search.inStock || false,
})

// Update local state when URL changes
useEffect(() => {
setLocalFilters({
minPrice: search.minPrice || 0,
maxPrice: search.maxPrice || 1000,
inStock: search.inStock || false,
})
}, [search.minPrice, search.maxPrice, search.inStock])

const applyFilters = () => {
navigate({
search: (prev) => ({
...prev,
...localFilters,
page: 1, // Reset pagination
}),
})
}

const resetFilters = () => {
const defaultFilters = { minPrice: 0, maxPrice: 1000, inStock: false }
setLocalFilters(defaultFilters)

navigate({
search: (prev) => {
const { minPrice, maxPrice, inStock, ...rest } = prev
return rest
},
})
}

return (
<div>
<label>
Min Price:
<input
type="number"
value={localFilters.minPrice}
onChange={(e) =>
setLocalFilters((prev) => ({
...prev,
minPrice: parseInt(e.target.value) || 0,
}))
}
/>
</label>

<label>
Max Price:
<input
type="number"
value={localFilters.maxPrice}
onChange={(e) =>
setLocalFilters((prev) => ({
...prev,
maxPrice: parseInt(e.target.value) || 1000,
}))
}
/>
</label>

<label>
<input
type="checkbox"
checked={localFilters.inStock}
onChange={(e) =>
setLocalFilters((prev) => ({
...prev,
inStock: e.target.checked,
}))
}
/>
In Stock Only
</label>

<button onClick={applyFilters}>Apply Filters</button>
<button onClick={resetFilters}>Reset</button>
</div>
)
}

검색 매개변수 검증을 사용하는 폼

const handleFormSubmit = (formData: FormData) => {
const query = formData.get('query') as string
const page = parseInt(formData.get('page') as string) || 1

safeNavigate({ query, page })
}

return (
<form action={handleFormSubmit}>
<input name="query" placeholder="Search..." required />
<input name="page" type="number" defaultValue="1" />
<button type="submit">Search</button>
</form>
)

구현 참고 사항

필요한 추가 콘텐츠:

  • 검색 매개변수를 사용하는 비제어 폼 패턴
  • 실시간 업데이트를 사용하는 제어 폼 패턴
  • 폼 라이브러리 통합(React Hook Form, Formik)
  • 디바운스된 URL 폼 업데이트
  • 폼 재설정 및 기본값 처리
  • URL 상태를 사용하는 다단계 폼
  • 검색 상태를 사용하는 파일 업로드 폼
  • URL 피드백을 사용하는 폼 검증 오류 처리

추가할 상호 참조:

  • 기초 내용을 위한 setup-basic-search-params.md 링크
  • 탐색 패턴을 위한 navigate-with-search-params.md 링크
  • 폼 검증을 위한 validate-search-params.md 링크
  • 디바운싱을 위한 optimize-search-param-performance.md의 후속 링크

필요한 README 업데이트:

  • 점진적 시리즈에서 가이드가 완료되었음을 표시
  • 관련 가이드에서 "일반적인 다음 단계" 주석 해제