우선 저번 포스팅에서 대시보드에 관해 포스트를 작성하기로 했는데 작업을 하다보니 이미 만들어진 로직들도 있고 컴포넌트들도 구현되어 있어서 마땅히 적을만한 내용이 없었다. 그래서 세세한 내용들까지 포스팅으로 적을 필요까지 없을 것 같아 버그를 수정한 내용을 적어보겠다.
기능적인 버그는 아니다. 지금 배포까지 끝난 상태이고 전체적으로 잘 동작한다. 하지만 서비스 전체적으로 작은 버그들이 존재한다. 이런 버그들이 큰 문제인가 싶지만 내가 사용자라도 애매한 버그들이 눈에 보이면 사용할 기회가 많이 줄어들 것 같다. 그래서 너무 사소한 버그는 후순위로 미루고 당장 사용자가 사용하기에 눈에 많이 띄는 것만 수정해보려고 한다.
현재 우리 서비스에 location과 sort값으로 searchParams로 설정해서 값을 저장하고 있다.

해당 값을 설정했을때에도 잘 설정되고 이에 맞는 정보도 잘 받아온다. 그럼 어떤 문제가 있는가? 해당 페이지에서 뒤로가기를 눌렀을때 searchParams의 값이 아닌 컴포넌트의 기본값으로 세팅이 된다. 하지만 데이터는 searchParams의 값이다. 쉽게 얘기하면 데이터와 컴포넌트 상태가 다르다는 것이다.
해결 방향은 간단하다. 기본값을 설정하는 함수를 작성해주면 된다.
react를 써봤다면 이런 문제는 쉽게 해소가 가능하다. useEffect를 사용해서 location이나 sort값이 있으면 state값을 변경시켜주면 된다.
const [currentSort, setCurrentSort] = useState('recent');
const currentSortKorean = sorts.find((sort) => sort.en === currentSort)?.ko || '최신순';
...
const handleClickSort = ({ name, value }: { name: string; value: string }) => {
router.push(`${pathname}?${createQueryString(name, value)}`);
setCurrentSort(value);
};
기존의 코드를 보면 초기값으로 설정해주고 sort버튼을 누르면 값이 변경되도록 설정되어 있다. 하지만 만약 사용자가
https://gila.vercel.app/activity-list?location=%EC%84%9C%EC%9A%B8%ED%8A%B9%EB%B3%84%EC%8B%9C+%EC%A4%91%EA%B5%AC&sort=mostViewed
해당 경로를 복사를 하거나 즐겨찾기를 해뒀을 경우에 해당 경로로 접근하면 기초 값인 최신순으로 설정된다는 것이다.
const searchParams = useSearchParams();
현재 route의 searchParams를 가져오고
useEffect(() => {
const sortValue = searchParams.get('sort');
if (sortValue) {
setCurrentSort(sortValue);
}
}, [searchParams]);
useEffect를 통해 sort값이 있으면 세팅해주는 것이다. 이제 간단하게 문제가 해결됬다. location drawer도 동일한 방법으로 해주면 된다.
동일한 방법으로 수정하긴 했지만 약간 아쉬운 것들이 있어서 내가 작성한 코드가 아니지만 수정해보기로 했다. 아쉬운 점은 두가지이다.
- 지역선택시 drawer안닫힘
세종특별자치시라는 예외 케이스로인해 대분류의 지역만 선택해도 searchParam이 세팅되면서 데이터를 받아옴
첫번째 아쉬운점은 간단하게 해결이 가능하지만 두번째의 경우는 불필요한 요청이 간다는 점에서 반드시 수정해야하는 상황이였다. 물론 대분류의 지역만 선택했을때에도 나오는 데이터가 있다면 문제없지만 우리는 소분류 지역까지 선택하도록 만들었기 때문이다.
onSelect={(value) => {
setSelectedLocation(value);
setProvince(value);
const params = new URLSearchParams(searchParams.toString());
params.set('location', value);
router.push(`?${params.toString()}`);
}}
전에 작성된 코드이다. 첫번째 대분류를 선택했을경우 세종특별자치시라는 소분류가 없는 경우를 피하기 위해 이 경우에도 location을 searchParam으로 설정해준다. 하지만 내 생각에는 하나의 예외경우를 피하기 위해 전체 로직을 예외에 맞춰서 작성하는 것은 비효율적이라고 생각했다.
const handleSelectProvince = (provinceLocation: string) => {
if (provinceLocation === '세종특별자치시') {
const params = new URLSearchParams(searchParams.toString());
params.set('location', provinceLocation);
router.push(`?${params.toString()}`);
} else {
setProvince(provinceLocation);
}
};
그래서 대분류에 해당하는 로직을 작성했다. 만약 세종특별자치시의 경우에만 searchParam을 설정해주고 그 외의 경우에는 state의 값만 설정해주는 것이다. 여기에서 설정된 province값은
const handleSelectLocation = (location: string) => {
if (province) {
const fullLocation = `${province} ${location}`;
setSelectedLocation(fullLocation);
const params = new URLSearchParams(searchParams.toString());
params.set('location', fullLocation);
router.push(`?${params.toString()}`);
}
};
이렇게 소분류를 클릭했을때 활용해서 searchParam을 설정하고 location에 맞는 데이터를 받아오도록 설정해줬다.
그리고 추가적으로 drawer가 닫히도록 로직을 작성해줬다.
useEffect(() => {
const locationValue = searchParams.get('location');
if (!locationValue) {
setProvince(null);
setSelectedLocation(null);
} else {
setSelectedLocation(locationValue);
setIsDrawOpen(false);
}
}, [searchParams]);
우선 초기화를 했을때에는 사용자에게 다시 location을 설정하도록 drawer를 닫지는 않는다. 반대로 location을 설정해서 route가 변경되면 자동으로 drawer를 닫아준다. 그래서 바로 컨텐츠로 넘어가도록 만들어줬다.
shadcn의 drawer도 내가 작성한 코드가 아니고 location drawer도 팀원이 작성한 코드이다 보니 처음에 어떤 방식으로 동작하고 설계되었는지 바로 파악하기 어려웠다. 하지만 내가 원하는대로 동작하고 개선된 것을 보니 조금은 뿌듯하다.
반대로 내가 작성한 코드를 누군가 리팩토링하거나 보는 경우가 생길텐데 과연 내가 작성한 코드는 가독성이 좋은지 고민하게 된다. 내가 보기엔 나쁘지 않은데 이건 내가 작성했으니까 당연한 것이다. 코드를 작성할때 더 신경써서 작성하고 커밋도 세세하게 작성해야겠다.
다음은 추가적인 기능들을 넣어줄것이다. 현재 서비스가 전체적으로는 완성되어 있지만 과연 이런 서비스를 시장에 내놓았을때 어떨까를 생각하고 있다. 이정도는 있어야하지 않나?라는 생각을 가지고 있다. 아마 위치기반 서비스, 채팅 서비스가 주된 기능이 되지 않을까 싶다. 더 완벽하게 만들어보자.