Hell路 World 삐약-
[React] indexOf, includes, 정규식 RegExp로 대소문자 구분 없는 검색 기능 구현하기 본문
Reactjs

[React] indexOf, includes, 정규식 RegExp로 대소문자 구분 없는 검색 기능 구현하기

날으는쏘피 2021. 9. 15.
728x90

오늘은 지난시간에 배운 검색기능을 구현하는 세가지 방법을 복습하는 포스팅!

 

 

사실 검색기능 자체를 구현하는 코드는 자바스크립트식이기때문에 자바스크립트 게시판에 쓰려고 하다가... 그래도 리액트 수업시간에 했던 예제라 리액트 게시판에 쓰기로 했다. 일단 사용법만 익혀두면 여기저기서 정말 많이 쓰게될 것 같다. 특히 정규식 RegExp!!

 

 

일단 기능구현 자체가 목적이니 간단하게 데이터를 준비한다. 생각나는 연예인 이름을 줄줄 썼는데 영문검색 대소문자 필터링을 해야하기때문에 영문 데이터도 몇개 넣었다.

 

 

검색한 단어가 바뀔때마다 화면을 다시 그려주기때문에 useEffect를 사용한다.

42번째 줄, useEffect내에서 data상태를 설정해주는데 전체 데이터에서 filter로 해당값만 찾아준다. 이때 두 단어를 비교할때 사용하는 함수가 indexOf()이다. (아래 다시 설명)

 

import React, { useEffect, useState } from 'react';

const Search = () => {

    const [data, setData] = useState(dataList) //데이터 상태설정 
    const [search, setSearch] = useState('') //검색어 상태설정
    
    const inputChange = (e)=>{
        const {value} = e.target
        setSearch(value)
    }

    useEffect(()=>{
        setData(
            dataList.filter(item => item.name.indexOf(search) !== -1)
        )
    }, [search])

    return (
        <div>
            <p>
                <input type="text" placeholder="검색어를 입력하세요" value={search} onChange={inputChange}/>
                <button>Search</button>
            </p>
            <ul>
                {
                    data.map(item => <li key={item.id}>{item.name}</li>)
                }
            </ul>
            
        </div>
    );
};

export default Search;

 

반응형

· indexOf

문자열 내에서 찾고자 하는 문자의 첫번째 위치값(index)을 반환한다. 값이 없을경우엔 -1을 반환

var anyString = 'Brave new world';

console.log('The index of the first w from the beginning is ' + anyString.indexOf('w'));
// 첫번째 w 문자 위치는 8
console.log(anyString.indexOf('q'))
// -1을 반환

 

따라서 -1을 반환하면 그 값이 없음을 의미함으로 위 코드의 43번 줄 

dataList.filter(item => item.name.indexOf(search) !== -1)

는 indexOf값이 -1이 아닌것, 즉 값이 있는것, true인 얘들만 필터링한다.

 

 

String.prototype.indexOf() - JavaScript | MDN

indexOf() 메서드는 호출한 String 객체에서 주어진 값과 일치하는 첫 번째 인덱스를 반환합니다. 일치하는 값이 없으면 -1을 반환합니다.

developer.mozilla.org

그런데 이녀석 너무 똑똑한 나머지 대소문자를 구문한다

그래서 그냥 저렇게만 해버리면 영어이름을 검색할때 난감해진다

소문자 e를 검색하면 대문자 E가 들어간 에릭남과 에픽하이는 검색조건에서 제외가 되어버리는 것이다. 이런 오류를 방지하기위해 아예 데이터와 검색어를 비교하는 수식에서 비교대상을 모두 소문자로 바꾸거나 대문자로 바꿔주어야 한다.

 

dataList.filter(item => item.name.toLowerCase().indexOf(search.toLowerCase()) !== -1)

 

 

· includes

문자열 내에 찾고자 하는 문자가 있을 경우 true, 없을 경우 false를 반환한다

 

 

String.prototype.includes() - JavaScript | MDN

includes() 메서드는 하나의 문자열이 다른 문자열에 포함되어 있는지를 판별하고, 결과를 true 또는 false 로 반환합니다.

developer.mozilla.org

 

indexOf는 찾고자하는 문자열의 위치값을 반환하기때문에 보통은 이메일주소나 핸드폰번호를 표시할때 @이나 -표로 구문하는 문자열에서 종종 사용했던걸로 기억한다. 그런데 이런 검색기능을 구현할때는 굳이 그렇게 할 필요가 없으니 간단하게 includes를 사용하면 코드가 아주 쬐끔 짧아진다(ㅋㅋㅋ)

 

dataList.filter(item => item.name.toLowerCase().includes(search.toLowerCase()))

 

728x90

· RegExp

정규표현식(Regular Expression)을 사용하기 위한 객체를 생성한다.

 

회원가입이나 아이디 비밀번호 설정등에서 많이 본 정규표현식. 그중에서도 이번 예제처럼 검색기능에 쓰기에 아주 좋은 기능이 있는데 바로 정규식 메소드와 플래그를 이용한 고급검색기능이다

 

 

정규 표현식 - JavaScript | MDN

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 RegExp의 exec 메소드와 test 메소드  ,

developer.mozilla.org

 

 

그래서 최종적으로 RegExp을 사용한 검색 기능 코드는 아래와 같다

 

dataList.filter(item =>{
                const re = new RegExp(search, 'gi') //g는 전역, i는 대소문자 구분없이
                return item.name.match(re)
            })

 

 

+추가로 위 코드처럼만 실행하면 input창에 타이핑하는대로 실시간으로 데이터가 필터링되는데 검색버튼을 눌렀을때만 실행하고자하면 아래처럼 setData를 click함수로 따로 만들어 검색버튼에 적용하고 useEffect의 변수도 검색값(search)이 아닌 data값으로 변경해주면 된다

 

//~
const click=()=>{
        setData(
            dataList.filter(item =>{
                const re = new RegExp(search, 'gi')
                return item.name.match(re)
            })
        )
    }
    
useEffect(()=>{
 		}, [data]) //데이터가 바뀔때마다 화면을 다시 그려라

 

 


공부하며 정리하는 초보 개발자입니다.

포스팅 내용에 잘못된 점이나 더 좋은 방법이 있다면 댓글로 알려주시면 감사하겠습니다 :)

728x90
Comments