지난 번 useQuery
를 이용해서 검색어에 일치하는 데이터를 불러오고
해당 데이터를 보여주는 부분까지는 성공을 했다.
하지만 기획상으로 해당 검색어와 일치하는 글자를 볼드처리 해야하는 과정이 남아있었다.
갓구글.. 역시 개발자는 구글링이 8할이다.
구글에 오늘 TIL 제목과 같은 형태로 검색해보니
정말 다양한 검색어 하이라이트 처리에 대한 글들이 쏟아졌었다.
그 중, jQuery
로 구현한 검색어 하이라이트 or 볼드처리에 관한 글들이 많아서
정작 내 코드에서 직접 구현하기 어려운 상황이었다.
그래서 생각해 본 바로는, 검색어
와 검색어에 따른 결과 문자열
을 이용해서
결과 문자열에서 검색어 부분을 자르고 해당 부분만 볼드 처리를 한 뒤,
다시 문자열을 합쳐서 보여주는 방식으로 진행해야겠다
라는 로직을 생각했는데, 자르기 위해 split
메소드를 사용했을 때,
해당 검색어가 사라지는 상황이 생겨버렸다.
그래서 역시 다시 구글링으로..
const highlightIncludedText = (text: string, value: string) => {
const title = text.toLowerCase();
const searchValue = value.toLowerCase();
if (searchValue !== '' && title.includes(searchValue)) {
const matchText = text.split(new RegExp(`(${searchValue})`, 'gi'));
);
return (
<>
{matchText.map((text, index) =>
text.toLowerCase() === searchValue.toLowerCase() ? (
<span key={index} style={{ fontWeight: 700 }}>
{text}
</span>
) : (
text
),
)}
</>
);
}
return text;
};
하나의 함수를 생성하고, 검색어
와 해당 검색어에 따른 결과값
을 인자로 받는다.
받은 인자끼리 일치 한 후, 비교해 주기 위해서 전부 소문자로 변경하고
검색어가 공백이 아니거나, 결과값에 검색어가 포함되어 있을 때,
new RegExp()
를 활용해 매치 되는 검색어를 기준으로 문자열을 배열로 만들어 준다.
예를 들어,
const title = "react Router"
const searchValue = "react"
const matchText = text.split(new RegExp(`(${searchValue})`, 'gi'));
라고 한다면 배열로 나오는 결과 값은
['react',' Router']
가 도출되게 된다.
그렇게 나온 배열을 map
함수를 이용해 검색어와 일치하는 부분만
인라인 스타일로 폰트 크기를 굵게 해주는 로직으로 구현이 되었다.
검색 결과는 의도하는 대로 잘 나온 것을 확인했다.
조금 의아했던 부분은 new RegExp
부분이 정규표현식을 활용하는 부분인데
new RegExp(정규표현식, flag)
가 들어가게 되는데
정규표현식 부분에 ${seachValue}
가 아닌 (${seachValue})
처럼
해당 부분을 괄호로 감싸주어야만 검색어 부분이 사라지지 않고,
배열로 나뉘어서 보여진 다는 점이 신기했다.. 이유는.. 점차 알아보자...