어떤 기능을 넣어볼까 하다가 검색창 기능이 많이 보여서 넣어 보기로 했다.
const [search, setSearch] = useState("");
const onChange = (e) => {
setSearch(e.target.value)
}
먼저 검색창에 검색어와 변화를 알기위해 useState
hooks를 선언한다.
그 다음 변화된 value값을 변경해 주기 위해 onChange
함수를 사용한다.
<input type="text" value={search} onChange={onChange} />
<input>
태그로 검색창을 만들고 속성에 value
안에는 value값을 읽을수 있게 state
를 선언. 또 value를 변경하기 위해 onChange
함수도 선언한다.
const filterTitle = movies.filter((p) => {
return p.title.toLocaleLowerCase().includes(search.toLocaleLowerCase())
})
filter
함수를 사용할 변수를 만들어주자.
검색어와 같은 값들만 걸러내기 위해서는 filter
함수가 필요하다.
인자 값은 임의로 설정해 주고, 테스트하기 위해 영화의 제목만 가져와 보자.
includes
함수는 배열의 특정 요소가 포함하는지 판별해 주는 boolean타입으로 입력한 검색어를 true & false로 나눠준다.
includes
함수는 대문자와 소문자를 인식(구분)하기 때문에 toLocaleLowerCase
함수로 입력값과 제목을 소문자로 동일 시켜주었다.
<div>
{filterTitle.map(movie => <div><span>{movie.title}</span>
</div>)}
배열안의 내용을 풀어주기 위해 filter
함수가 담긴 filterTitle
에 map
함수를 사용해서 title을 가져와보자.
const filterTitle = movies.filter((p) => {
return p.title.replace(" ","").toLocaleLowerCase().includes(search.toLocaleLowerCase().replace(" ",""))
})
추가로 replace
를 활용해서 공백을 모두 없애 띄어쓰기 혹은 붙여쓰기할때도 검색에 이상이 없게 만들어 주었다.
예시)
전) Fantastic Beats the secrets
후) fantasticbeatsthesecrets
상위 컴포넌트(부모)와 하위 컴포넌트(자식)로 역할을 나눠주자.
import PropTypes from "prop-types"
function SearchBar({search,onChange}) {
return (
<div>
<input className="input" type="text" value={search} onChange={onChange}/>
</div>
)
}
SearchBar.propTypes={
search: PropTypes.any.isRequired,
onChange:PropTypes.func.isRequired,
}
export default SearchBar;
영화정보를 보내주는 컴포넌트는 기존의 Movie컴포넌트를 사용한다.
전달해 줄 props는 value
와 oncChange
함수
PropTypes를 지정해 주면 마무리
return (
<div>{loading ? <Loader /> :
<div>
<Header />
<SearchBar value={search} onChange={onChange}/>
{filterTitle.map(movie =>
<Movie
id={movie.id}
key={movie.id}
poster_path={movie.poster_path}
title={movie.title}
average={movie.vote_average}
/>
)}
</div>
}
</div>
)
SearchBar
하위 컴포넌트를 넣어주고 value & onChange props를 채워준다.
filterTitle
을 기존에 있던 Movie 컴포넌트를 가져와서 사용하였다.
css를 입혀주고 마무리 하였다.
검색창 만들기 도움되었어요! 감사합니다