본문 바로가기
Javascript, Typescript, React

쿼리스트링(=검색 파라미터) 다루는 방법

by 케이리케리 2024. 3. 7.

useLocation, useSearchParams, URLSearchParams

useLocation()

  • React Router에서 제공하는 훅이며, 현재 브라우저의 위치(location) 객체를 반환
const location = useLocation();
  • Properties
    • pathname : 현재 주소의 경로 (쿼리 스트링 제외)
    • search : ?(물음표) 문자를 포함한 쿼리 스트링
    • hash : 주소의 # 문자 뒤의 값 (해시 라우터에서 사용)
    • state : 페이지로 이동할 때 임의로 넣을 수 있는 상태 값
    • key : location 객체의 고유 값. 초기에는 default이고 페이지가 변경될 때마다 고유 값이 생성됨
  • location.search를 통해 ? 문자를 포함한 쿼리 스트링을 추출할 수 있음
  • useLocation 훅을 사용하면 현재 URL의 변경을 감지하고, 이에 따른 특정 작업을 수행할 수 있습니다.
  • 현재 URL의 정보를 알고 싶을 때 사용. 또는 리액트 컴포넌트 내에서 현재 경로나 쿼리 등의 변경을 감지하고 싶을 때 사용
//type ViewMode = 'grid' | 'list';

function BooksList({ books }: Props) {
  const [view, setView] = useState<ViewMode>('grid');
  const location = useLocation();

  useEffect(() => {
    const params = new URLSearchParams(location.search);

    if (params.get(QUERYSTRING.VIEW)) {
      setView(params.get(QUERYSTRING.VIEW) as ViewMode);
    }
  }, [location.search]);

  return (
    <BooksListStyle view={view}>
      {books?.map((item) => {
        return <BookItem key={item.id} book={item} view={view} />;
      })}
    </BooksListStyle>
  );
}

URLSearchParams 생성자

  • 웹 API의 일부로, 브라우저에 내장된 객체이다. URL의 쿼리 문자열을 쉽게 파싱하고, 조작할 수 있는 메소드를 제공
  • URLSearchParams는 직접적으로 URL과 관련된 작업을 수행할 때 사용되며, 쿼리 문자열을 구성하거나, 변경하거나, 쿼리 파라미터의 값을 가져올 때 유용
  • 쿼리스트링(search)을 제외한 주소가 필요없을 때 사용할 수 있는 방법
  • URLSearchParams 객체의 생성

URLSearchParams 객체의 생성자는 여러 형태의 값을 인자로 받을 수 있음

 

1. 파라미터의 키와 값의 쌍으로 이루어진 2차원 배열

new URLSearchParams([
  ["mode", "dark"],
  ["page", 1],
  ["draft", false],
  ["sort", "email"],
  ["sort", "date"],
]);

 

2. 쿼리 스트링을 문자열의 형태

new URLSearchParams("?mode=dark&page=1&draft=false");

 

3. 맨 앞에 ? 기호는 생략이 가능

new URLSearchParams("mode=dark&page=1&draft=false");
  • 내장 메서드는 URL 객체의 searchParams와 동일
  • URLSearchParams 객체의 메서드
const searchParams = new URLSearchParams();

// append(key, value)은 기존 파라미터 키에 새로운 값을 추가
searchParams.append("mode", "dark");

// set(key, value)은 기존 값을 지워버리고 새로운 값을 추가
searchParams.set("page", 1);
searchParams.set("sort", "email");
searchParams.set("sort", "date");

// 객체에 저장되어 있는 값을 읽을 때
// get(key)은 첫 번째 값만 반환
searchParams.get("sort"); // 'date'

// getAll(key)은 모든 값을 배열로 반환
searchParams.getAll("mode"); // [ 'dark' ]

// 쿼리 스트링을 string 형태로 리턴
searchParams.toString(); //'mode=dark&page=1&sort=date'

// delete(key)은 파라미터를 삭제하고 싶을 때
// 인자로 키를 넘기면 해당 키에 해당하는 모든 값이 함께 삭제
searchParams.delete("sort");

// has()은 단순히 특정 파라미터의 존재 여부를 알고 싶을 때
searchParams.has("draft"); // false

useSearchParams()

  • React Router에서 제공하는 훅이고, 현재 위치의 URL에서 쿼리 문자열을 읽고 수정하는 데 사용
  • URL 중에서도 ?key=value 형태의 검색 부분만을 대상으로 하여 이 부분만을 변경하거나 업데이트
  • 두 가지 값을 배열로 반환
const [searchParams, setSearchParams] = useSearchParams();
// [ 현재 위치의 검색 파라미터,  이를 업데이트하는 데 사용할 수 있는 함수 ] = useSearchParams();
  • searchParams - URLSearchParams 객체
  • setSearchParams - 이 객체를 업데이트할 수 있는 함수
  • URLSearchParams 인터페이스를 사용 → URLSearchParams의 메서드 이용 O
  • searchParams를 변경하는 메서드를 이용해서 searchParams의 값을 변경하더라도 실제 URL의 쿼리 스트링은 변경되지 않는다.
  • 변경된 searchParams를 이용해서 실제 쿼리 스트링을 변경시키려면 setSearchParams 함수에 searchParams를 인자로 전달하면서 호출해야 한다.
import { useSearchParams } from 'react-router-dom';

const List = () => {
  const [searchParams, setSearchParams] = useSearchParams();

  const setSortParams = () => {
    searchParams.set('sort', 'clear');
    setSearchParams(searchParams);
  };

  const appendSortParams = () => {
    searchParams.append('sort', 'hello-world');
    setSearchParams(searchParams);
  };

 

✅ useSearchParams 훅을 사용할 때 URLSearchParams 객체를 추가로 사용하는 이유

URLSearchParams 를 사용하지 않아도 useSearchParams로만 실제 url의 쿼리 스트링을 변경할 수 있는데 왜 URLSearchParams 을 사용해야할까?

function BooksFilter() {
  const { category } = useCategory();
  const [searchParams, setSearchParams] = useSearchParams();

  const handleCategory = (id: number | null) => {
    const newSearchParams = new URLSearchParams(searchParams);

    if (id === null) {
      newSearchParams.delete(QUERYSTRING.CATEGORY_ID);
    } else {
      newSearchParams.set(QUERYSTRING.CATEGORY_ID, id.toString());
    }

    setSearchParams(newSearchParams);
  };

	...

	return (...);
}

 

  • useSearchParams로부터 반환되는 searchParams는 실제 URL의 쿼리 스트링을 반영하는 URLSearchParams의 인스턴스이다.

그러나 직접 이 인스턴스를 수정하는 것은 권장 X

새로운 URLSearchParams 객체를 생성하고 → 필요한 변경사항을 적용 → 이를 setSearchParams 함수에 전달하여 URL을 업데이트하는 방식이 일반적

  1. searchParams 객체를 직접 수정하는 대신 새로운 객체를 생성하면, 불변성 유지 가능
  2. 새 URLSearchParams 객체를 만들고 명확하게 변경 사항을 적용함으로써, 코드의 의도가 더 명확 → 가독성 및 유지보수성

등의 이유로 useSearchParams 훅을 사용할 때 URLSearchParams 객체를 추가로 사용한다고 한다.

 

 

참고 자료

https://www.zerocho.com/category/HTML&DOM/post/5b3ae84fb3dabd001b53b9ab

https://www.daleseo.com/js-url-search-params/

https://velog.io/@hdmoon127/Query-String-feat.-useLocation-useSearchParams