앞선 TIL 에서
내 벨로그 > 글 > 태그목록 태그 목록을 구현하는데 NavLink를 사용했다. 그런데 스타일 active가 원하는 대로 적용되지 않았다. 처음에는 end 때문인줄 알았지만 생각해보면 태그 목록에서는 path 이동을 하지 않는다. 그래서 발생한 문제다! 태그 목록은 쿼리스트링을 받아서 주소가 변경되기 때문에 쿼리가 바뀔 때마다 className이 바뀌거나 active를 활성화 할 수 있는 조건을 주어서 사용할 수 있어야한다.
라고 했다. 생각한 방법은 간단하다. 먼저 네브링크를 만들어 주고 내가 부여한 쿼리스트링을 찾아 active를 주면 된다. 하지만 어떻게 해야할까?
먼저 NavLink
을 import 해준다.
import { NavLink } from "react-router-dom";
const TagList = () => {
const list = [
{
id: 1,
name: "전체보기",
},
{
id: 2,
name: "javascript",
},
{
id: 3,
name: "React",
},
{
id: 4,
name: "html",
},
{
id: 5,
name: "css",
},
];
return (
<>
{list.map((tag) => {
return (
<NavLink key={tag.id} to={tag.id === 1 ? "" : `?tag=${tag.name}`}>
{tag.name}
</NavLink>
);
})}
</>
);
};
export default TagList;
이런 식으로 네브링크를 구성하게 되면,
태그 목록에서 전체보기는 기본 값, 'javascript'면 ?tag=javascript
'React' ?tag=React
url이 바뀌는 것을 볼 수 있다. 우리는 그것을 이용해야한다.
먼저 useLocation
을 import 해준다.
import { NavLink, useLocation } from "react-router-dom";
const TagList = () => {
const location = useLocation();
console.log(location); //콘솔에 찍어 보자!
const list = [
...];
return (
<>
...
</>
);
}
export default TagList;
location
을 콘솔에 찍어보면, 네브링크를 이동할 때마다 pathname
은 그대로고 (그래서 이번 태그목록을 만드는 일에는 end
가 쓰일 일이 없다)search
에 우리가 원하는 파라미터가 찍히는 것을 볼 수 있다.
console.log(location.search)
그럼 이제 답이 거의 다 나왔다. 전달 된 쿼리스트링을 읽어오면 된다. 그런데 JS를 사용해 전달된 파라미터의 값을 어떻게 가져올 수 있을까?
split()은 특정 문자를 기준으로 문자열을 자르기 때문에 기호를 기준으로 잘라 원하는 값을 찾을 수 있다. 다만 족금 귀찮을 수 있기에....
최근 브라우저에서는 URLSearchParams
를 사용해 원하는 값을 간단하고 빠르게 가져올 수 있다.
사용하기
먼저 location.search
를 URLSearchParams
로 넘겨준다.
const 파라미터 = new URLSearchParams(location.search);
'파라미터'에 URLSearchParams
를 사용해 담아준다. 기본값은 {}가 나온다
const 태그 = (파라미터.get("tag"));
tag
로 검색된 value값을 가져오기 위해 get()을 사용해준다.
그리고 console 찍어보면
console.log(태그);
이제 원하는 값을 얻었다 😃😃😃😃
className
에 조건을 주면 된다.
import { NavLink, useLocation } from "react-router-dom";
const TagList = () => {
const location = useLocation();
const list = [
...];
return (
<>
{list.map((tag) => {
return (
<NavLink
key={tag.id}
to={tag.id === 1 ? "" : `?tag=${tag.name}`}
className={() => {
const url = new URLSearchParams(location.search);
const getTag = url.get('tag');
let className = '기본클래스네임';
if (getTag === tag.name ||(!location.search && tag.name === '전체보기')) className += ' active';
return className;
}}
>
{tag.name}
</NavLink>
);
})}
</>
);
};
export default TagList;
받아온 쿼리와 네브링크의 이름이 일치할때 스타일 active 활성화 시켜줄 수 있게 한다. '전체보기'는 default 값이기 때문에 location.search
가 존재하지 않으면서 '전체보기'일 때 조건을 한 번 더 걸어주면 된다.
@끝
location.search
는 굳이 useLocation
을 import 해주지 않아도 된다. 왜인지 다시 알아봐야겠다.
그리고 지금의 기능은 사실 무조건 NavLink로 해야하는 것은 아니어서 굳이 NavLink로 해야만 하나 싶은데 Link를 이용해서 하려고 하니 더 복잡한 것 같다. 그래서 className
에 함수를 줄 수 있는 NavLink로 사용하게 되었지만, 다른 방법도 연구해 봐야겠다.
@진짜 끝.