
다음과 같은 자동완성기능을 구현해야했슴다.
문제는..
유저가 행정구역의 정식명칭을 철자 그대로 입력할것이라고 기대하면 안된다는 것이죠...
예를들어 유저가 '서울', '서울시'등 정식적인 행정구역명을 입력하지않더라도 '서울특별시'의 데이터로 필터링돼야 합니다.
문제는 여기서 발생합니다. JavaScript의 메서드인 includes는 저러한 기능을 수행하기에는 너무너무 부족합니다.
예를들어 유저가 입력한 '서울'은 includes메서드로 '서울특별시'를 필터링할 수 있겠지만, 만약 유저가 '서울시'를 입력한다면 '서울특별시'로 걸러주지 못합니다.. 시/군/구 단위 뿐만 아니라 법정동 단위도 문제였습니다.
단편적인 예로 목동같은경우 목1동, 목2동..등등 이있고 창신동도 정식적인 명칭으로 세분화하자면 '창신제1동' 등등과 같이 유저가 입력한 단어를 필터링해주기에는 너무너무 복잡했죠.
정규식을 복잡하게 구성해야하나, json파일을 좀 수정해줘야하나 고민하던 찰나..
리액트의 라이브러리생태계에는 없는 것이 없다는 믿음하에 라이브러리 폭풍검색에 돌입하게 됩니다. 그러다 발견했죠. fuse.js
어차피 복잡한 내용은 공식문서에서 확인하실 수 있을테니, 기본적인 사용예시만 보여드리겠습니다.
사용예시
다음과 같은 '행정동.json'이 있다고 가정해보겠습니다.
[
{
"행정동코드": "1117063000",
"행정동": "서울특별시 용산구 이촌제1동"
},
{
"행정동코드": "1117064000",
"행정동": "서울특별시 용산구 이촌제2동"
},
{
"행정동코드": "1117065000",
"행정동": "서울특별시 용산구 이태원제1동"
},
{
"행정동코드": "1117066000",
"행정동": "서울특별시 용산구 이태원제2동"
}
]
필터링기능을 사용해야하는 곳에서
import를 해준뒤 옵션을 작성합니다.(fuseOptions) keys에는 필터링하고싶은 객체의 key가 들어갑니다.
유저의 인풋값은 행정동코드가 아닌 행정동을 기준으로 필터링하기때문에 저는 key: ['행정동']으로만 작성했습니다.
new Fuse생성자 함수의 첫번째 인자로는 json파일 명칭을 입력하고(행정동.json의 행정동), 두번째 인자로는 먼저 작성한 옵션을 넣습니다. 그렇게 만들어진 객체에는 search메서드가 있는데 search메서드에 입력값을 넣어주면 끝입니다.
import Fuse from 'fuse.js';
const fuseOptions = {
keys: ['행정동'],
};
const fuse = new Fuse(행정동, fuseOptions);
fuse.search(input)
이렇게 간단하게만 작성해도 필터링이 아주 잘 됩니다. (debounce를 300ms로만 작성했는데도 gif라 느려보이네요.)
