
URL 쿼리 스트링과 React 리액트 상태 관리의 만남: nuqs 사용법 가이드
안녕하세요!
오늘은 React 애플리케이션에서 URL 쿼리 스트링을 활용해 상태를 관리할 수 있게 도와주는 nuqs라는 라이브러리를 소개하겠습니다.
nuqs는 간단하고 타입 안전하며, Next.js, React Router, Remix 등 다양한 React 기반 프레임워크와 함께 사용할 수 있습니다.
이 글은 튜토리얼 형식으로 작성되었으니, 단계별로 따라 하면서 nuqs의 매력을 체험해 보세요!
1️⃣ 시작하기: nuqs 설치
먼저 nuqs를 설치해야 합니다.
프로젝트 루트 디렉토리에서 다음 명령어 중 하나를 실행하세요.
# npm
npm install nuqs
# yarn
yarn add nuqs
# pnpm
pnpm add nuqs
설치가 완료되었다면 준비 완료입니다! 이제 본격적으로 nuqs를 사용해 보겠습니다.
2️⃣ 기본 사용법: useQueryState
nuqs의 핵심은 useQueryState라는 훅입니다.
이 훅을 사용하면 URL 쿼리 스트링을 마치 useState처럼 쉽게 다룰 수 있습니다.
다음은 간단한 예제입니다. URL 쿼리 스트링에 name 값을 저장하고 읽는 애플리케이션을 만들어 보겠습니다.
예제 코드
'use client'
import { useQueryState } from 'nuqs'
export default function App() {
const [name, setName] = useQueryState('name') // 쿼리 키: 'name'
return (
<div style={{ padding: '20px' }}>
<h1>안녕하세요, {name || '방문자'}님!</h1>
<input
type="text"
value={name || ''}
onChange={(e) => setName(e.target.value)}
placeholder="이름을 입력하세요"
/>
<button onClick={() => setName(null)}>초기화</button>
</div>
)
}
결과 확인
- 애플리케이션을 실행한 후 브라우저에서 확인하세요.
- 입력 필드에 이름을 입력하면 URL이 자동으로 업데이트됩니다. 예:
http://localhost:3000/?name=John - "초기화" 버튼을 클릭하면 URL에서
name값이 제거됩니다.
3️⃣ 숫자, 날짜, 배열 등 다양한 타입 처리하기
nuqs는 문자열뿐만 아니라 숫자, 날짜, 배열 등 다양한 타입을 처리할 수 있도록 파서(parser)를 제공합니다.
아래 예제에서 숫자와 배열을 다루는 방법을 알아봅시다.
숫자와 배열 다루기
'use client'
import { useQueryState, parseAsInteger, parseAsArrayOf } from 'nuqs'
export default function App() {
const [count, setCount] = useQueryState('count', parseAsInteger.withDefault(0)) // 기본값: 0
const [tags, setTags] = useQueryState('tags', parseAsArrayOf((v) => v)) // 문자열 배열
return (
<div style={{ padding: '20px' }}>
<h1>카운트: {count}</h1>
<button onClick={() => setCount((c) => c + 1)}>+1</button>
<button onClick={() => setCount((c) => c - 1)}>-1</button>
<button onClick={() => setCount(null)}>초기화</button>
<h2>태그</h2>
<input
type="text"
placeholder="태그를 콤마(,)로 구분하여 입력하세요"
onBlur={(e) => setTags(e.target.value.split(','))}
/>
<p>입력한 태그: {tags?.join(', ') || '없음'}</p>
<button onClick={() => setTags(null)}>태그 초기화</button>
</div>
)
}
주요 기능 설명:
parseAsInteger: 쿼리 값을 숫자로 변환합니다. 기본값(withDefault)을 설정하면 URL에 값이 없을 때 기본값을 반환합니다.parseAsArrayOf: 배열 값을 처리합니다. 위 코드에서는 입력된 문자열을 콤마로 나눠 배열로 변환했습니다.
결과
- 카운트 버튼을 클릭하면 URL에
count값이 업데이트됩니다.- 예:
http://localhost:3000/?count=5
- 예:
- 태그를 입력하고 URL에 반영된 결과를 확인하세요.
- 예:
http://localhost:3000/?tags=React,Next.js,JavaScript
- 예:
4️⃣ 여러 상태를 한 번에 관리하기: useQueryStates
useQueryStates를 사용하면 여러 상태를 객체 형태로 묶어 관리할 수 있습니다.
예를 들어, 좌표값(lat, lng)을 동시에 처리하려면 다음과 같이 작성할 수 있습니다.
좌표값 관리하기
'use client'
import { useQueryStates, parseAsFloat } from 'nuqs'
export default function App() {
const [coordinates, setCoordinates] = useQueryStates({
lat: parseAsFloat.withDefault(37.5665), // 기본값: 서울 위도
lng: parseAsFloat.withDefault(126.9780) // 기본값: 서울 경도
})
const updateCoordinates = () => {
setCoordinates({
lat: Math.random() * 180 - 90, // 위도: -90 ~ 90
lng: Math.random() * 360 - 180 // 경도: -180 ~ 180
})
}
return (
<div style={{ padding: '20px' }}>
<h1>현재 좌표</h1>
<p>위도: {coordinates.lat}</p>
<p>경도: {coordinates.lng}</p>
<button onClick={updateCoordinates}>무작위 좌표 생성</button>
<button onClick={() => setCoordinates(null)}>초기화</button>
</div>
)
}
결과
- "무작위 좌표 생성" 버튼을 클릭하면 URL에 새로운
lat과lng값이 반영됩니다. - URL 예:
http://localhost:3000/?lat=12.3456&lng=78.9101 - "초기화" 버튼을 클릭하면 좌표값이 기본값으로 초기화됩니다.
5️⃣ Next.js에서의 사용법
nuqs는 Next.js의 pages와 app 라우터를 모두 지원합니다.
Next.js 앱에서 nuqs를 사용하려면 NuqsAdapter를 프로젝트의 최상위 컴포넌트(예: _app.tsx 또는 layout.tsx)에 추가해야 합니다.
NuqsAdapter 설정
App Router (layout.tsx)
import { NuqsAdapter } from 'nuqs/adapters/next/app'
export default function RootLayout({ children }) {
return (
<html>
<body>
<NuqsAdapter>{children}</NuqsAdapter>
</body>
</html>
)
}
Pages Router (_app.tsx)
import { NuqsAdapter } from 'nuqs/adapters/next/pages'
export default function MyApp({ Component, pageProps }) {
return (
<NuqsAdapter>
<Component {...pageProps} />
</NuqsAdapter>
)
}
6️⃣ 고급 기능: 사용자 정의 파서
nuqs는 기본 제공 파서 외에 사용자 정의 파서를 지원합니다.
예를 들어, 16진수 색상 값을 처리하려면 다음과 같이 작성할 수 있습니다.
import { useQueryState, createParser } from 'nuqs'
const hexColorParser = createParser({
parse: (query) => `#${query}`, // URL 쿼리를 16진수 색상으로 변환
serialize: (value) => value.replace('#', '') // '#RRGGBB' → 'RRGGBB'
})
export default function App() {
const [color, setColor] = useQueryState('color', hexColorParser.withDefault('#000000'))
return (
<div style={{ backgroundColor: color, padding: '20px', color: '#fff' }}>
<h1>현재 색상: {color}</h1>
<button onClick={() => setColor('#ff0000')}>빨강</button>
<button onClick={() => setColor('#00ff00')}>초록</button>
<button onClick={() => setColor('#0000ff')}>파랑</button>
</div>
)
}
결론
nuqs를 사용하면 URL 쿼리 스트링을 통해 상태를 관리하면서도 React의 상태 관리 방식을 그대로 유지할 수 있습니다.
이 라이브러리는 특히 Next.js와 같은 서버-클라이언트 통합 프레임워크에서 강력한 도구로 활용될 수 있습니다.
여러분도 프로젝트에서 nuqs를 사용해 보세요. URL 기반으로 상태를 관리하는 새로운 패러다임을 경험할 수 있을 것입니다.
더 자세한 내용은 공식 문서를 참고하세요.
'Javascript' 카테고리의 다른 글
| RegExp.escape() 마스터하기: 정규표현식 이스케이프 처리 완벽 가이드 (0) | 2025.02.13 |
|---|---|
| 리액트 폼 데이터 저장, 이제 Nuqs로 완벽하게 해결하세요! (0) | 2025.02.09 |
| Vite React vs Next.js: 더 나은 선택은? Hono와 함께하는 최신 웹 개발 트렌드 (0) | 2025.02.09 |
| 더 이상 느린 리액트는 없다: 리액트 컴파일러 완벽 가이드 (0) | 2025.02.04 |
| React useState 업데이트 함수의 비밀: 최신 상태를 참조하는 마법 (디버깅으로 더 쉽게!) (1) | 2025.01.22 |