// Search 컴포넌트 constSearch=()=>{// ...// 앞서 data 객체에서 edges 가져와 posts에 저장const posts = data.allMarkdownRemark.edges
// posts 순회하면서 필터링하기const filteredPosts: PostType[]= posts.filter((post: PostType)=>{// frontmatter에서 필터링에 사용할 title과 tags를 구조분해할당으로 가져오기const{ title, tags }= post.node.frontmatter
// 태그들의 문자열을 모두 소문자로 바꾸고, 정규표현식을 사용해 모든 띄워쓰기 없애기const lowerTags = tags.map((tag:string)=> tag.toLowerCase().replace(//g,''))// 검색 input에 들어간 query 문자열 역시 소문자로 바꾸고, 띄워쓰기 없앤 뒤, 태그들에서 query 문자열과 같은 tag 필터링하기const tagsQuery = lowerTags.includes(query.toLowerCase().replace(//g,''))// 제목 title도 소문자로 바꾸고, 띄워쓰기 없앤 뒤, 검색어로 필터링하기const titleQuery = title.toLowerCase().replace(//g,'').includes(query.toLowerCase().replace(//g,''))return(// 필터링된 제목이나 태그가 있고, 검색 input에 공백없이 검색 문자열이 있으면 해당 필터링 결과를 리턴하기(titleQuery || tagsQuery)&& query.replace(//g,'').length !==0)});// ...};
4. 필터링된 검색결과 출력하기
// Search 검색 결과 출력constSearch=()=>{return(<div>{/*...*/}{/*위에서 필터링되어 리턴된 posts 순회하기*/}<p>검색 결과는 <b>{filteredPosts.length}</b> 개 입니다</p><div>{filteredPosts.map(({ node }, index)=>(// 클릭 시, 해당 글 페이지로 이동<NavLinkkey={index}to={node.fields.slug}>{/*썸네일 이미지*/}<figure><GatsbyImagealt="thumbnail"image={node.frontmatter.thumbnail.childImageSharp.gatsbyImageData}css={searchResultThumbnailStyle}/></figure>{/*제목과 작성일*/}<div><span>{node.frontmatter.title}</span><span>{node.frontmatter.date}</span></div></NavLink>))}</div>{/*...*/}</div>);};exportdefault Search;
검색 기능 구현 결과
Emotion.js의 Styled Component로 스타일링까지 적용하여 검색 기능을 최종적으로 구현한 모습은 아래와 같다.