URL
URL 객체는 웹 주소(URL)를 파싱하고 조작하기 위한 JavaScript의 내장 API
URL 객체를 사용하면 URL의 각 구성 요소(프로토콜, 호스트, 경로, 쿼리 매개변수 등)에 쉽게 접근하고 수정 가능
https://www.example.com:8080/path/to/page?name=value&search=test#section
└─┬─┘ └─────┬─────┘ └─┬──┘└─────┬─────┘└───────┬─────────────┘└──┬──┘
프로토콜 호스트 포트 경로 쿼리 매개변수 해시(프래그먼트)
URLSearchParams
URLSearchParams 객체는 URL의 쿼리 문자열(query string)을 쉽게 처리하기 위한 API
URL의 ? 뒤에 오는 부분(예: ?name=value&search=test)을 파싱하여 각 매개변수에 접근하고 조작 가능
URL 객체 사용 방법
// URL 객체 생성
const url = new URL('https://www.example.com:8080/path/to/page?name=value&search=test#section');
// URL 구성 요소에 접근
console.log(url.protocol);// 'https:'
console.log(url.hostname);// 'www.example.com'
console.log(url.host);// 'www.example.com:8080'
console.log(url.port);// '8080'
console.log(url.pathname);// '/path/to/page'
console.log(url.search);// '?name=value&search=test'
console.log(url.hash);// '#section'
console.log(url.origin);// 'https://www.example.com:8080'
URL 객체 수정하기
const url = new URL('https://www.example.com/cart');
// 경로 변경
url.pathname = '/products';
// 포트 추가
url.port = '3000';
// 쿼리 매개변수 추가
url.searchParams.append('category', 'books');
// 결과 확인
console.log(url.href);// 'https://www.example.com:3000/products?category=books'
상대 URL 처리
// 기본 URL을 기준으로 상대 URL 처리
const baseURL = new URL('https://www.example.com/products/');
const relativeURL = new URL('electronics', baseURL);
console.log(relativeURL.href);// 'https://www.example.com/products/electronics'
4. URLSearchParams 객체 사용 방법
기본 사용법
// 문자열로 URLSearchParams 생성
const params1 = new URLSearchParams('name=value&search=test');
// 객체로 URLSearchParams 생성
const params2 = new URLSearchParams({
category: 'books',
author: 'John Doe'
});
// URL 객체의 searchParams 속성을 통해 접근
const url = new URL('https://www.example.com/?page=1&limit=10');
const params3 = url.searchParams;
매개변수 다루기
const params = new URLSearchParams('category=books&price=20&inStock=true');
// 매개변수 값 가져오기
console.log(params.get('category'));// 'books'
console.log(params.get('price'));// '20'
console.log(params.has('inStock'));// true // 매개변수 존재 여부 확인
console.log(params.has('discount'));// false
params.append('author', 'Jane Doe'); // 매개변수 추가
// 매개변수 설정 (이미 존재하면 덮어씀)
params.set('price', '25');
// 매개변수 삭제
params.delete('inStock');
// 모든 매개변수 이름 가져오기
for (const key of params.keys()) {
console.log(key);// 'category', 'price', 'author'
}
// 모든 매개변수 값 가져오기
for (const value of params.values()) {
console.log(value);// 'books', '25', 'Jane Doe'
}
// 모든 매개변수 [이름, 값] 쌍 가져오기
for (const [key, value] of params.entries()) {
console.log(`${key}: ${value}`);
}
// 문자열로 변환
console.log(params.toString());// 'category=books&price=25&author=Jane%20Doe'
/shop 페이지에 접근하기 위해
import { detailPageLoader, shopPageLoader } from './loaders/productsLoaders'
브라우저에서 /shop 접속
React Router가 해당 경로의 loader부터 실행
shopPageLoader가 실행
const filteredRelatedProducts = relatedProducts.filter(p => p.id !== product.id)
return { product, filteredRelatedProducts }
} catch (err) {
console.log('err----', err)
throw new Response('상품 데이터를 가져오는 중 오류 발생', {
status: err.status || 500,
})
}
}
export const shopPageLoader = async ({ request }) => {
// console.log('productsLoaders.js:info', request.url)
const url = new URL(request.url)
const page = url.searchParams.get('_page') || 1
const per_page = url.searchParams.get('_per_page') || 12
const category = url.searchParams.get('category') || ''
const sort = url.searchParams.get('_sort') || ''
// const per_page = 12
let queryString = `_page=${page}&_per_page=${per_page}`
category ? (queryString += `&category=${category}`) : queryString
sort ? (queryString += `&_sort=${sort}`) : queryString
console.log('-----------------', queryString)
try {
const products = await getProductsData(queryString)
console.log('productsLoaders.js:products ----- ', products)
return { products, per_page }
처음 접속할 대 → URL에 아무 파라미터가 없어도 기본값으로 _page = 1, _per_page = 12
category와 sort가 없으면 전체 상품을 기본 정렬로 가져온다.
카테고리 필터 작용
const handleCategoryFilter = category => {
const params = new URLSearchParams(searchParams)
params.set('_page', 1)
params.set('_per_page', per_page)
category ? params.set('category', category) : params.delete('category')
navigate(`/shop/?${params}`)
}
- 전체상품 버튼: category 파라미터를 삭제 ('' → 모든 상품)
- 신상품 버튼: category=new → shopPageLoader에서 필터링됨
- 인기상품 버튼: category=top → 동일하게 처리됨
정렬 작용 방법
const handleSort = sortOption => {
const params = new URLSearchParams(searchParams)
params.set('_page', 1)
params.set('_sort', sortOption)
navigate(`/shop/?${params}`)
}
- 등록순 → _sort=id
- 낮은 가격순 → _sort=price
- 높은 가격순 → _sort=-price
- 낮은 할인순 → _sort=discount
- 높은 할인순 → _sort=-discount
[사용자: /shop 접속]
↓
[Router → shopPageLoader 실행]
↓
[queryString에 따라 상품 불러옴]
↓
[ShopPage → useLoaderData()로 받아서 상품 렌더링]
↓
[사용자가 필터/정렬 버튼 클릭]
↓
[navigate로 URL 변경 → loader 재실행 → 새로운 상품 렌더링]
1. 접근하자마자 12개의 콘텐츠가 나오게 - 카테고리 구분 없이 나오게
2. 신상품을 나오면 카테고리가 new인 상품만 가져오기
인기상품은 카테고리가 top인 상품만 가져오기
등록수는 _sort를 활용하기 (낮은 가격순)
오늘 하루 요약

'💡 URECA > 🗒️ 스터디 노트' 카테고리의 다른 글
[URECA] Day 60 React Redux (0) | 2025.04.24 |
---|---|
[URECA] Day59 React 총정리 🐳 (개념 배울때마다 여기에 추가하기) (0) | 2025.04.23 |
[URECA] Day57 React Shop PROJ - CartPage, ShopPage (0) | 2025.04.21 |
[URECA] Day56 React PROJ SHOP (0) | 2025.04.18 |
[URECA] Day55 React Shop PROJ 4편 디바운스 & 쓰로틀 정복기, 프록시 서버 설정 (0) | 2025.04.17 |