"use-query-params": "^2.2.1",
import { QueryParamProvider } from "use-query-params";
import { ReactRouter6Adapter } from "use-query-params/adapters/react-router-6";
<HashRouter>
<QueryParamProvider adapter={ReactRouter6Adapter}>
//...
</QueryParamProvider>
</HashRouter>
const [query, setQuery] = useQueryParams({
label: StringParam,
name: StringParam,
regNo: StringParam,
accountsCeo: StringParam,
tagString: StringParam, // "A,B" 같은 문자열이면 StringParam
tag: StringParam, // ["A","B"] 배열이라면 ArrayParam
insertName: StringParam,
isDelete: StringParam,
});
const {
label: group, // 그룹
name, // 거래처이름
regNo, // 사업자등록번호
accountsCeo, // 대표자이름
insertName, // 생성자
tag, // 태그 (문자열 "A,B" 또는 배열)
isDelete, // 휴지통 포함 여부
} = query;
setQuery({ accountsCeo: undefined }, "replaceIn"),
1️⃣ useQueryParams가 돌려주는 setQuery는 URL 쿼리스트링을 갱신하는 함수예요.
2️⃣ setQuery({ label: undefined })는 label 파라미터를 URL에서 삭제한다는 뜻입니다.
3️⃣ 두 번째 인자 { replace: true }는 브라우저 히스토리에 새 기록을 남기지 않고(뒤로가기 한 단계가 늘어나지 않게), history.replaceState로 URL을 바꿉니다.
{ replace: false }(기본값인 경우가 많음)이면 *history.pushState가 되어 히스토리에 한 단계가 추가됩니다.✅ 왜 undefined를 쓰나?
setQuery({ label: undefined }) → label 키 자체를 제거setQuery({ label: "" }) → 빈 문자열로 세팅(키는 남음)setQuery({ label: null }) → 버전/파라미터 타입에 따라 문자열 "null"*로 들어가거나 무시될 수 있어 권장하지 않음** 👉 키를 지울 때는 undefined가 정석입니다.✅ 부분 업데이트(Partial Update)라는 점이 핵심
setQuery는 주어진 키만 변경/삭제하고, 나머지 쿼리는 그대로 유지합니다. 예) 현재 ?name=더존&label=영업1팀 일 때 setQuery({ label: undefined }) → ?name=더존 으로 변경 (name은 유지, label만 삭제)✅ 동작 흐름을 예시로 이해하기
// 1) 현재 URL: /accounts/searchresult?label=영업1팀&name=팀이름&isDelete=true
// 2) 어떤 칩(예: "그룹: 영업1팀")의 X를 눌렀을 때 실행:
() => setQuery({ label: undefined }, { replace: true });
// 3) 결과 URL: /accounts/searchresult?name=팀이름&isDelete=true
// - label만 제거!
// - replace:true 덕분에 뒤로가기로 label이 복원되는 "중간 단계"가 생기지 않음
✅ 실전 패턴(인덱스→삭제 액션 매핑) 요약
summaryLines를 만들 때 같은 순서의 removers 배열을 같이 만들어두고, handleDeleteTag(index)에서 removers[index]()를 호출하면 끝!setQuery({ label: undefined }, { replace: true })setQuery({ name: undefined }, { replace: true })setQuery({ tag: undefined }, { replace: true }) (배열이면 전체 삭제)setQuery({ isDelete: undefined }, { replace: true })✅ 자주 하는 질문
Q. 경로도 바뀌나요?
A. 아니요. pathname은 그대로이고 search만 바뀝니다.
Q. HashRouter인데 괜찮나요?
A. 네. 주소창은 #/accounts/searchresult?name=...처럼 보이지만, 내부적으로는 동일하게 동작합니다.
Q. 배열 파라미터는?
A. ArrayParam을 쓰고 있다면 setQuery({ tag: ['A','B'] })처럼 전체를 세팅하거나, 특정 항목만 빼고 다시 세팅하세요. 지우려면 undefined.
Q. 히스토리가 너무 길어져요
A. 검색 필터처럼 “자잘한 변경”은 { replace: true }가 UX에 좋아요(뒤로가기 스팸 방지).
📌 한 줄 요약
setQuery({ label: undefined }, { replace: true }) = label 쿼리 파라미터 삭제 + 히스토리 replaceundefined, 값 변경은 실제 값, 빈 값 유지면 ""