본문 바로가기
React/React Basic

Monsters-Rolodex 3 | 검색 기능|search(),filter(),includes()

by CodeMia 2022. 4. 27.

앞 포스트에서 몬스터 이름들이 모두 나오도록 해보았다. 

 

 

검색창 설치 하기 

이제는 인풋박스를 만들고 키워드를 한 자씩 입력하면 

해당하는 이름이 걸러져 나오도록 해보자.

 

 

 

1. 인풋 태그 만들기 

render 함수 안에 input 태그를 입력해 준다. 

 

 

인풋 태그가 생겼다. 

 

 

2. 이벤트 핸들러로 인풋 내용 받기 

input 안에 이벤트 핸들러를 넣어 입력 받은 내용으로 검색을 하도록 해보자. 

 

 

searchString 변수를 만들고

입력된 string을 소문자로 바꾸어 변수에 저장을 해둔다. 

 

 

이 입력된 string이 monsters array에 있는지를 검색해야 한다. 

이 때 filter(), include() 함수가 필요하다. 

 

 

3. searchString 을 state에 담기 

searchString은 계속 내용이 바뀌므로 state에 담는다. 

 

 

4. setState로 searchString 업데이트 하기 

this.setState()는 asymchronous하게 일어나는데 

this.setState({object}) 형태로 써놓으면

리액트 batch가 다른 컴포넌트 변화까지 같이 있는지 살피고

최적의 상황일 때 업데이트를 해준다. 

그래서 this.setState(()=>{}) 함수를 통과시켜 바로 호출하도록 한다.

 

return { searchString: fiteredMonsters } 를 

return { searchString }으로 바꾼다. 

this is just a quick shorthand when you're writing objects. 

If you use a variable as the only field, then what JS is going to do

and it says the key is going to be the name of this variable and

the value is going to be value of this variable. 

키에 있는 벨류가 그대로 들어가는 경우 키만 적어준다. 

 

 

5. 필터링한 아이템 새 array에 담기 

 

filteredMonsters array가 render() 안, return 밖에 위치하게 한다. 

onChange 안 콜백 함수에 있으면 scope 때문에 그 안에서만 적용된다. 

 

monsters array에 filter() 와 includes()를 사용해서 이름을 검색하고 

걸러져 나온 이름들을 filteredMonsters array 안에 담는다. 

 

includes() 함수는 

[{name: 'Leanne'}, {name: 'Ervin'}] 키 벨류 형식으로 되어 있는 array에서

name을 체크한 후 true, false를 리턴한다. 

name이 들어있으면 true로 아이템을 킵하고, false이면 버린다. 

킵한 아이템들을 모아 새 array를 만든다. 

 

 

6. 새 array를 map( )으로 돌려 이름 나오게 하기 

map에 연결된 array도 filteredMonsters로 바꿔준다.

 

 

 

잘 검색되는 것을 볼 수 있다. 

 

 


 

event.target.value를 쓰는 이유 

 

인풋창에 hello를 입력 후 

 

 

 

event 파라미터에 뭐가 있나 콘솔로 살펴보면 

 

 

 

많은 내용이 들어있지만 그 중에서도

target에서 입력한 내용이 들어있는 것을 볼 수 있다.

__ 언더 스코어 되어있는 것은 사용할 수 없고 

다른 키 벨류들은 다 사용할 수 있다.

 

 

 

event.target.value를 적어주면

input으로 들어오는 string을 받을 수 있다. 

 

 


 filter( ) 

filter() 함수는 들어온 array를 수정해서 보여주는 것이 아니라

새 array를 만들어 리턴해준다. 

 

filter() 안에 익명함수를 넣어서 

true, false가 나오는 질문을 하고 

true에 해당하는 아이템은 새 array에 담는다. 

 

myArray는 그대로 잘 있다. 


 

 includes( )  

다음과 같은 Array가 있다.

 

 

해당 내용이 myArray에 있는지 묻는다. 

 

 

index 까지 물을 수 있음 

index 3에서 부터 2가 있는지 묻기 

index 3은 4번째, 5번째 해당하는 [4, 5] 가 있고 2는 없다. 

 


 

글자 지워도 이름들이 안나오는 이유 

 

filteredMonsters array가 onChange 함수 안에 있는 경우 

한자씩 지우면 다시 이름들이 많아져야 하는데 이름들이 나오지가 않는다.

 

 

filter 실행전체 array가 아닌 현재 array에서 하고 있기 때문이다.

한 글자 한 글자 입력할 때마다 현재 array에 든 아이템은 줄어드는데

그 안에서 filter로 골라내니 나오는 이름이 없는 것이다. 

 

 

좀 더 이해를 돕기 위해 시작할 때 array와 ending array를 콘솔에 나오도록 해보자.

 

 

검색창에 leanne를 치면 

 

처음에는 아이템 10개에서 시작했지만, 뒤로 갈 수록 시작하는 아이템 갯수가 줄어드는 것을 볼 수 있다.

 

 


 

import { Component } from 'react';
import './App.css';

class App extends Component {
constructor() {
super();

this.state = {
monsters: [],
searchField: ''
};
}
componentDidMount() {
.then((response) => response.json())
.then((users) => this.setState(
() => {
return { monsters: users }
}
));
}

render() {
const filteredMonsters = this.state.monsters.filter((monster) => {
return monster.name.toLocaleLowerCase().includes(this.state.searchField);
});

return (
<div className="App">
<input clasName='search-box'
type='search'
placeholder='Search Monsters'
onChange={(event) => {
const searchField = event.target.value.toLocaleLowerCase();

this.setState(
() => {
return { searchField };
},
)
}}
/>
{filteredMonsters.map((monster) => {
return <div key={monster.id}>
<h1>{monster.name}</h1>
</div>;
})}
</div>
);
}
}

export default App;

 

 

댓글