웹 개발 시 주소(URL)를 다루는 것은 필수적이다.. (동적인 웹 애플리케이션에서는 URL의 특정 부분을 읽거나 수정해야 하는 경우가 많으니까)
이를 위해 이번 포스트에서는 JavaScript와 React Router에서 제공하는 주요 도구들을 정리해보겠다.
https://www.example.com:8080/path/to/page?name=value&search=test#section
└─┬─┘ └─────┬─────┘ └─┬──┘└─────┬─────┘└───────┬─────────────┘└──┬──┘
프로토콜 호스트 포트 경로 쿼리 매개변수 해시(프래그먼트)
protocol
: 'https:'
hostname
: 'example.com'
port
: '8080'
pathname
: '/path'
search
: '?name=value'&search=test
hash
: '#section'
origin
: 'https://example.com:8080'
href
: 전체 URL 문자열// URL 객체 생성
const myUrl = new URL('[https://store.example.com/products?id=123](https://store.example.com/products?id=123)');
// 속성 접근
console.log(myUrl.hostname); // 'store.example.com'
console.log(myUrl.pathname); // '/products'
console.log(myUrl.search); // '?id=123'
const modifiableUrl = new URL('[https://example.com/user](https://example.com/user)');
// 경로 변경
modifiableUrl.pathname = '/profile';
console.log(modifiableUrl.href); // '[https://example.com/profile](https://example.com/profile)'
// searchParams를 이용해 쿼리 파라미터 추가/수정
modifiableUrl.searchParams.set('mode', 'edit'); // ?mode=edit 추가
console.log(modifiableUrl.href); // '[https://example.com/profile?mode=edit](https://example.com/profile?mode=edit)'
const baseUrl = new URL('[https://api.example.com/v1/](https://api.example.com/v1/)');
const userApiUrl = new URL('users/1', baseUrl); // 상대 경로 결합
console.log(userApiUrl.href); // '[https://api.example.com/v1/users/1](https://api.example.com/v1/users/1)'
URLSerachParams
객체는 이제 쿼리문자열에 쉽게 접근하여 조작하게하는 치트키 도구라고 생각하면 된다.
?key=value&...
을 쉽게 다루기 위한 객체임.// 1. 문자열로 생성
const params1 = new URLSearchParams('q=js&sort=popular');
// 2. 객체로 생성
const params2 = new URLSearchParams({ page: '1', limit: '10' });
// 3. URL 객체에서 얻기
const url = new URL('[https://example.com/?type=image](https://example.com/?type=image)');
const params3 = url.searchParams; // URLSearchParams 객체
console.log(params3.get('type')); // 'image'
const params = new URLSearchParams('category=books');
// 값 가져오기 (get)
console.log(params.get('category')); // 'books'
// 파라미터 존재 확인 (has)
console.log(params.has('category')); // true
// 파라미터 추가 (append)
params.append('lang', 'en'); // category=books&lang=en
// 파라미터 설정 (set) - 덮어쓰거나 추가
params.set('category', 'web'); // category=web&lang=en
// 파라미터 삭제 (delete)
params.delete('lang'); // category=web
// 문자열로 변환 (toString)
console.log(params.toString()); // 'category=web'
// 검색 조건
const options = { query: 'React', limit: 5 };
const apiUrl = new URL('[https://api.example.com/search](https://api.example.com/search)');
// 조건 객체를 쿼리 파라미터로 추가
Object.entries(options).forEach(([key, value]) => {
apiUrl.searchParams.append(key, value);
});
console.log(apiUrl.href);
// '[https://api.example.com/search?query=React&limit=5](https://api.example.com/search?query=React&limit=5)'
import { useSearchParams } from 'react-router-dom';
function MyComponent() {
// searchParams: 읽기용 URLSearchParams 인스턴스
// setSearchParams: URL 업데이트 함수
const [searchParams, setSearchParams] = useSearchParams();
// ...
}
searchParams.get('param')
사용.setSearchParams({ key: 'value' })
호출 시 URL 변경 및 리렌더링.import React from 'react';
import { useSearchParams } from 'react-router-dom';
function SimpleFilter() {
const [searchParams, setSearchParams] = useSearchParams();
const filter = searchParams.get('filter') || 'all'; // 'filter' 값 읽기
const handleFilterChange = (newFilter) => {
// setSearchParams로 URL 업데이트 (?filter=값)
// 참고: 객체를 전달하면 해당 키만 남기고 나머지는 제거될 수 있음
// 기존 파라미터 유지가 필요하면 new URLSearchParams(searchParams)로 복사 후 조작
setSearchParams({ filter: newFilter });
};
return (
<div>
<button onClick={() => handleFilterChange('active')}>활성</button>
<button onClick={() => handleFilterChange('completed')}>완료</button>
<button onClick={() => handleFilterChange('all')}>전체</button>
<p>현재 필터: {filter}</p>
{/* 필터된 데이터 표시 로직 */}
</div>
);
}
export default SimpleFilter;
-> ㅇㅇ
React Router를 사용하는 현대적인 React 애플리케이션에서는 URL 쿼리 파라미터를 컴포넌트 내에서 다룰 때, 주로 useSearchParams 훅을 사용하는 것이 표준적인 방법이다.
React 상태 및 렌더링과의 통합: useSearchParams
훅은 쿼리 파라미터의 변경을 React의 상태 관리 및 렌더링 사이클과 자연스럽게 통합시켜 줌. setSearchParams
함수를 호출하면 URL이 변경될 뿐만 아니라, 해당 변경 사항을 감지하고 관련 컴포넌트가 자동으로 다시 렌더링됨.
React Router와의 연동: React Router는 클라이언트 사이드 라우팅을 관리함. setSearchParams
는 단순히 URL을 바꾸는 것을 넘어 React Router의 네비게이션 메커니즘과 연동되어 브라우저 히스토리 스택을 올바르게 관리함 (뒤로 가기/앞으로 가기 동작).
편의성: 훅을 사용하면 URLSearchParams
객체를 직접 생성하거나 window.location
을 수동으로 파싱할 필요 없이, 현재 URL의 쿼리 파라미터에 쉽게 접근하고 업데이트할 수 있는 인터페이스([searchParams, setSearchParams])
를 제공받음.
-> 그렇다고 URLSearchParams를 아예 안 쓰는 것은 아님
useSearchParams
훅 자체가 반환하는 searchParams
객체가 바로 URLSearchParams
의 인스턴스임. 따라서, 파라미터 값을 읽거나(searchParams.get('key'))
, 특정 키가 있는지 확인할 때(searchParams.has('key'))
는 결국 URLSearchParams
의 메서드를 사용하게 됨.
React 컴포넌트 외부에서 URL 문자열을 직접 다뤄야 할 때는 여전히 네이티브 URLSearchParams
객체를 직접 생성해서 사용할 수 있음.