
리액트 폼 데이터 저장, 이제 Nuqs로 완벽하게 해결하세요!
안녕하세요! 웹 개발을 하다 보면 폼 데이터 때문에 머리가 아픈 순간이 많죠?
사용자 입력 내용을 저장하거나 페이지 새로고침을 처리하고, 심지어는 사용자 간에 폼 상태를 공유해야 할 때도 있습니다.
전통적인 방법들도 있지만, 요즘은 더 똑똑하고 세련된 방법들이 많이 등장했답니다!
오늘은 Nuqs를 사용해서 이러한 문제들을 어떻게 우아하게 해결할 수 있는지 알아볼까요?
과거의 방법과 한계점
1. 로컬 스토리지 (localStorage)
옛날 옛적에 개발자들은 브라우저의 localStorage를 사용해서 폼 데이터를 저장했답니다.
// 폼 데이터 저장
localStorage.setItem("formData", JSON.stringify(formData));
// 폼 데이터 불러오기
const savedData = JSON.parse(localStorage.getItem("formData"));
하지만 이 방법에는 몇 가지 치명적인 단점이 있었어요.
- 데이터 공유 불가: 여러 사용자 간에 데이터를 공유할 수 없습니다.
- 상태 관리 추가 필요: 추가적인 상태 관리 설정이 필수적입니다.
- 데이터 검증 기능 없음: 내장된 데이터 검증 기능이 없어요.
2. URL 파라미터와 데이터베이스 조합
좀 더 발전된 방법으로는 폼 데이터를 데이터베이스에 저장하고, 고유 ID를 생성하여 localStorage와 URL 파라미터에 ID를 저장한 후, 이를 통해 데이터를 조회하는 방법이 있습니다.
- 폼 데이터를 데이터베이스에 저장
- 고유 ID 생성
- ID를
localStorage와 URL 파라미터에 저장 - ID를 이용하여 데이터 불러오기
이 방법은 작동하지만, 상당한 백엔드 인프라 구축과 섬세한 구현이 필요하다는 단점이 있습니다.
Nuqs: 폼 데이터 저장의 혁명!
자, 이제 구세주처럼 등장한 Nuqs를 소개합니다! Nuqs는 리액트를 위한 타입 안전한 검색 파라미터 상태 관리 라이브러리인데요, 앞서 말한 문제들을 말끔하게 해결해준답니다!
- 타입 안전성 보장: 타입스크립트 기반이라 오류 걱정은 뚝!
- URL 기반 상태 관리: URL만 있으면 어디든지 데이터를 가져갈 수 있습니다!
- 손쉬운 데이터 검증: 데이터 유효성 검사도 간편하게!
- 공유 가능한 폼 상태: URL만 공유하면 폼 상태도 공유됩니다!
- 백엔드 불필요: 오직 클라이언트 측에서만 작동합니다!
Nuqs로 폼 데이터 저장하기
이제 React Hook Form, Zod, Nuqs를 사용하여 검증 기능을 갖춘 폼을 만들어 봅시다!
import { useQueryState, parseAsJson } from "nuqs";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
// 스키마 정의
const statusEnum = ["working", "chilling", "cooking"];
const formSchema = z.object({
firstName: z.string(),
lastName: z.string(),
status: z.enum(statusEnum),
});
type FormSchemaType = z.infer<typeof formSchema>;
function MyForm() {
// Nuqs 상태 초기화
const [jsonData, setJsonData] = useQueryState(
"json",
parseAsJson(formSchema.parse)
);
// React Hook Form으로 폼 설정
const form = useForm<FormSchemaType>({
resolver: zodResolver(formSchema),
values: jsonData, // URL 데이터로 폼 미리 채우기
});
const handleSubmit = form.handleSubmit((data) => {
console.log(data);
setJsonData(data); // URL 상태 업데이트
});
return (
<form onSubmit={handleSubmit}>
<TextInput label="First name" {...form.register("firstName")} />
<TextInput label="Last name" {...form.register("lastName")} />
<SelectInput
label="Status"
options={statusEnum}
{...form.register("status")}
/>
<Button type="submit">Submit</Button>
</form>
);
}
이 방식의 장점:
- 자동 저장: 폼 데이터가 URL에 자동으로 저장됩니다!
- 손쉬운 공유: URL을 복사하여 폼 상태를 다른 사람과 공유할 수 있습니다!
- 타입 안전성: Zod 유효성 검사를 통한 타입스크립트 지원!
- 간단한 구현: 최소한의 코드만 필요합니다!
- 백엔드 불필요: 완전히 클라이언트 측에서 작동합니다!
- 브라우저 통합: 브라우저 기록 및 북마크와 연동됩니다!
폼을 제출하면 폼 데이터가 URL에 나타납니다.
예: https://app.com?json={"firstName":"Joey","lastName":"Tribbiani","status":"chilling"} (실제로는 URL 인코딩됨).
라우터 통합 및 탐색 기록
Nuqs의 강력한 기능 중 하나는 React Router, Next, Remix와 같은 리액트 라우터와의 완벽한 통합입니다.
제대로 구성되면 폼 상태에 대한 브라우저 기록 기능을 활성화할 수 있습니다.
React Router와 Nuqs를 통합하는 방법은 다음과 같습니다.
import { NuqsAdapter } from "nuqs/adapters/react-router/v6";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import App from "./App";
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
]);
export function ReactRouter() {
return (
<NuqsAdapter>
<RouterProvider router={router} />
</NuqsAdapter>
);
}
기록 탐색 활성화
기본적으로 Nuqs는 폼 상태가 변경될 때 현재 URL을 대체합니다.
전체 기록 탐색 지원을 활성화하려면 withOptions를 사용하여 명시적으로 구성해야 합니다.
const [jsonData, setJsonData] = useQueryState(
"json",
parseAsJson(formSchema.parse)
.withDefault({
firstName: "",
lastName: "",
status: "working",
})
.withOptions({
history: "push", // 각 상태 변경에 대한 새 기록 항목 생성
})
);
history가 활성화되면 다음과 같은 추가 기능을 사용할 수 있습니다.
- 새 기록 항목 생성: 각 폼 변경은 새 브라우저 기록 항목을 생성합니다.
- 탐색 가능: 사용자는 브라우저 뒤로/앞으로 버튼을 사용하여 폼 상태를 탐색할 수 있습니다.
- 상태 보존: 폼 상태 변경 사항은 탐색 기록에 보존됩니다.
- 멀티 스텝 폼에 적합: 다단계 폼이나 폼 상태 변경 사항을 추적하려는 경우에 이상적입니다.
기본값 설정하기
Nuqs를 사용하면 기본 폼 상태를 쉽게 처리할 수 있습니다.
React Hook Form에서 수동으로 기본값을 설정하는 대신, Nuqs 쿼리 상태에서 직접 정의할 수 있습니다.
const [jsonData, setJsonData] = useQueryState(
"json",
parseAsJson(formSchema.parse).withDefault({
firstName: "",
lastName: "",
status: "working",
})
);
이렇게 하면 URL 매개변수가 없더라도 폼에 항상 유효한 초기 상태가 있는지 확인할 수 있습니다.
기본값은 다음과 같은 경우에 사용됩니다.
- 페이지 초기 로드: URL 매개변수 없이 페이지가 처음 로드될 때
- URL 매개변수 제거: URL 매개변수가 지워질 때
- 유효성 검사 실패: URL 매개변수가 유효성 검사에 실패할 때
나머지 폼 구현은 동일하게 유지되지만, 이제 jsonData가 undefined가 아니라는 것을 확신할 수 있습니다.
공유 기능 추가하기
URL 기반 저장소를 최대한 활용하려면 공유 버튼을 추가할 수 있습니다.
function ShareButton() {
const handleShare = () => {
navigator.clipboard.writeText(window.location.href);
// 성공 알림 추가
};
return <Button onClick={handleShare}>폼 공유</Button>;
}
결론
Nuqs는 개발자와 사용자 모두에게 친숙한 강력하고 타입 안전한 폼 상태 지속성 솔루션을 제공합니다.
URL 매개변수를 활용하여 복잡한 백엔드 저장소의 필요성을 없애는 동시에, 쉬운 공유 및 상태 관리를 가능하게 합니다.
Nuqs를 도입하여 보다 효율적이고 사용자 친화적인 웹 애플리케이션을 만들어보세요!
'Javascript' 카테고리의 다른 글
| TypeScript의 템플릿 리터럴 타입: 타입 검사 중 파싱 및 활용 방법 (0) | 2025.02.13 |
|---|---|
| RegExp.escape() 마스터하기: 정규표현식 이스케이프 처리 완벽 가이드 (0) | 2025.02.13 |
| URL 쿼리 스트링과 React 리액트 상태 관리의 만남: `nuqs` 사용법 가이드 (1) | 2025.02.09 |
| Vite React vs Next.js: 더 나은 선택은? Hono와 함께하는 최신 웹 개발 트렌드 (0) | 2025.02.09 |
| 더 이상 느린 리액트는 없다: 리액트 컴파일러 완벽 가이드 (0) | 2025.02.04 |