직원 관리 페이지에서 소속(회사) 필터를 구현하는데, 드롭다운에서 "xx주식회사"를 선택하면 URL이 이렇게 됐다.
/users?licenseName=xx주식회사
한글이 URL에 그대로 들어가니까 뭔가 찝찝했다. 인코딩 문제도 생길 수 있고, 백엔드에서 처리하기도 애매하다.
value와 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
}
결과:
드롭다운 옵션 만들 때 value랑 label 분리하는 건 기본인데, 이걸 URL 쿼리 파라미터까지 연결해서 생각하니까 조금 복잡해졌다.
특히 동적 데이터일 때 표시값 변환하는 부분을 놓치기 쉬운 것 같다.