URL 쿼리 파라미터와 UI 표시값 분리하기

Melon Coder·2026년 1월 20일

Trouble shooting

목록 보기
5/9

문제 상황

직원 관리 페이지에서 소속(회사) 필터를 구현하는데, 드롭다운에서 "xx주식회사"를 선택하면 URL이 이렇게 됐다.

/users?licenseName=xx주식회사

한글이 URL에 그대로 들어가니까 뭔가 찝찝했다. 인코딩 문제도 생길 수 있고, 백엔드에서 처리하기도 애매하다.


해결 방향

valuelabel을 분리하면 된다.

  • value: 서버로 보내는 값 (ID, 코드 등)
  • label: 사용자에게 보여주는 값 (한글 이름)
// 변경 전
const options = data?.map(v => ({ 
  value: v.name,      // 한글
  label: v.name 
}))

// 변경 후
const options = data?.map(v => ({ 
  value: v.licenseSeq,  // 숫자 ID
  label: v.name         // 한글
}))

이제 URL은 깔끔하게 숫자로 들어간다.
/users?licenseName=5

그러나,,


새로운 문제 발생

필터 Chip에 "소속: 5"라고 뜬다. 사용자 입장에서 5가 뭔지 알 수가 없다.

// 기존 코드 - 정적 옵션에서 label 찾기
const option = filterInfo.options?.find(opt => opt.value === value)
const displayValue = option ? option.label : value  // 못 찾으면 value 그대로 표시

문제는 소속 옵션이 API에서 동적으로 가져오는 데이터라서, filterInfo.options가 비어있다는 것.


최종 해결

동적 데이터인 경우 API 응답에서 직접 찾도록 분기 처리했다.

const { data: licenseFilter } = useGetLicenseFilter()

// getActiveFilters 함수 내부
if (filterKey === 'licenseName') {
  // 동적 데이터에서 찾기
  const license = licenseFilter?.find(l => l.licenseSeq === Number(value))
  displayValue = license?.name ?? value
} else {
  // 정적 옵션에서 찾기
  const option = filterInfo.options?.find(opt => opt.value === value)
  displayValue = option ? option.label : value
}

결과:

  • URL: ?licenseName=5
  • Chip: 소속: xx주식회사

정리

드롭다운 옵션 만들 때 value랑 label 분리하는 건 기본인데, 이걸 URL 쿼리 파라미터까지 연결해서 생각하니까 조금 복잡해졌다.
특히 동적 데이터일 때 표시값 변환하는 부분을 놓치기 쉬운 것 같다.

profile
Frontend developer

0개의 댓글