React HighLight recoil을 곁들인.

이지원·2023년 3월 23일
1

프로젝트 작업도중 키워드를 통해 게시물을 조회하는 부분을 진행하고 있었다
조회된 게시물은 하이라이트 기능을 사용해야 했다.

참고로 하이라이트 기능은 아래사진과 같이 검색된 키워드가 표시? 등 찾기쉽게 보여지는것을 뜻한다.

바로 적용해보자!
실제로 바닐라 js로도 충분히 만들 수 있을것같았지만
나는 개인적으로 라이브러리를 선호하는편이라서 바로 찾아보니 괜찮은 라이브러리를 발견했다.

react-highlight-words

라이브러리 문서

사용방법은 문서에서 볼 수 있듯이

<Highlighter
   highlightClassName="YourHighlightClass"
   searchWords={["and", "or", "the"]}
   autoEscape={true}
   textToHighlight="The dog is chasing the cat. Or perhaps they're just playing?"
 />

사실상 searchWords props에 하이라이트 찾을 배열을 전달하고
textToHighlight props에 키워드를 포함한 모든 텍스트를 전달해주면된다.

매우 간단하다!
방법으로는 이렇게 끝이라 여기까지 봐도 이해할것이다.
키워드를 recoil의 atom과 selector를 이용해서 해결했다.
아래 상황부터는

키워드 처리

내가 작업하고 있던 환경은
게시물 컴포넌트랑 키워드를 조회하는 컴포넌트는 서로 분리되어 있어서
키워드를 전역으로 관리했다.
라이브러리는 recoil을 사용하였다.

atom

import { atom } from 'recoil';

const keywordAtom = atom({
  key: '@atom/keyword',
  default: '',
});

export default keywordAtom;

우선 atom으로 검색할 문자열 전역변수를 만들고

selector

import { selector } from 'recoil';
import keywordAtom from '@src/recoils/atom/keyword';

const keywordSelector = selector({
  key: '@selector/keyword',
  get: ({ get }) => {
    const keyword = get(keywordAtom);
    return keyword.split(' ');
  },
});

export default keywordSelector;

selector를 이용하여 keywordAtom을 직접수정하는것이아닌 새로운 배열을 반환하는 전역변수를 만들었다.

이유?
atom 으로는 검색을 해서 원본 키워드로 검색을 하고
selector는 원본키워드를 이용해 하이라이트할 키워드를 변수로 추출해 전달해주기때문이다

게시물 컴포넌트

const keywordHighLight = useRecoilValue(keywordSelector);

return (
			<Highlighter
                  highlightStyle={{
                    backgroundColor: 'transparent',
                    color: theme.commonColor.pink004,
                  }}
                  // 하이라이트 css를 커스텀한다.
                  searchWords={keywordHighLight}
                  textToHighlight={community?.title}
                >
                  {community?.title}
                </Highlighter>
              </Title>
)

검색 컴포넌트

const setKeyword = useSetRecoilState(keywordAtom);
const onSearch = useCallback((value: string) => {
    setKeyword(value);
  }, []);
profile
안녕하세요 피드백은 언제나환영입니다.

0개의 댓글