[TIL] 검색어와 일치하는 글자 하이라이트

김명성·2022년 4월 13일
1

TIL

목록 보기
7/11
post-thumbnail

🧑🏻‍🏫 Intro

지난 번 useQuery를 이용해서 검색어에 일치하는 데이터를 불러오고
해당 데이터를 보여주는 부분까지는 성공을 했다.
하지만 기획상으로 해당 검색어와 일치하는 글자를 볼드처리 해야하는 과정이 남아있었다.

🧑🏻‍💻 과정

갓구글.. 역시 개발자는 구글링이 8할이다.

구글에 오늘 TIL 제목과 같은 형태로 검색해보니
정말 다양한 검색어 하이라이트 처리에 대한 글들이 쏟아졌었다.

그 중, jQuery로 구현한 검색어 하이라이트 or 볼드처리에 관한 글들이 많아서
정작 내 코드에서 직접 구현하기 어려운 상황이었다.

그래서 생각해 본 바로는, 검색어검색어에 따른 결과 문자열을 이용해서
결과 문자열에서 검색어 부분을 자르고 해당 부분만 볼드 처리를 한 뒤,
다시 문자열을 합쳐서 보여주는 방식으로 진행해야겠다

라는 로직을 생각했는데, 자르기 위해 split 메소드를 사용했을 때,
해당 검색어가 사라지는 상황이 생겨버렸다.

그래서 역시 다시 구글링으로..

💥 code

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}) 처럼
해당 부분을 괄호로 감싸주어야만 검색어 부분이 사라지지 않고,
배열로 나뉘어서 보여진 다는 점이 신기했다.. 이유는.. 점차 알아보자...


참고 문서

profile
잠재력은 핵폭탄급 Frontend Developer

0개의 댓글