React Web Structure Test7

리액트 디자인 / 검색기능 추가

Posted by ETHAN KIM on April 10, 2022 · 5 mins read
React

주요 개념

  • 검색 keyword를 parameter로 전달
  • Search 페이지 별도 구현
  • etc..(import 상대경로 -> 절대경로 수정작업 / 리팩토링 작업)


실습 환경

  • nodejs react 패키지


구현 결과


./Components/Structure/SearchBar/SearchBar.js

  • 검색 아이콘 클릭 시 navigate로 parameter 전달
//------------------------------ MODULE -------------------------------------
import { useState } from "react";
import styled from "styled-components";
import { FaSearch } from "react-icons/fa";
import { Link, useNavigate } from "react-router-dom";

//------------------------------ CSS ----------------------------------------
const StyledSearchBar = styled.div`
    border: solid 1px lightgrey;
    border-radius : 100px;
    padding:8px;
    height:17px;
    &>input{
        border:none;
        outline:none;
        width:97%;
        margin:none;
        vertical-align:text-top;
    }
`;
const StyledIcon = styled.span`
    cursor:pointer;
`;

//------------------------------ COMPONENT ----------------------------------
const SearchBar = () => {
    const [keyword, setKeyword] = useState(null);

    const navigate = useNavigate();

    const search_exec = () => {
        navigate(`/Search?keyword=${keyword}`);
    }

    const enterkey = () => {
        if(window.event.keyCode == 13){
            search_exec();
        }
    }    

    const onChangeInput = (e) => {
        setKeyword(e.target.value);
    };

    return(
        <>
        <StyledSearchBar>
            <input onChange={onChangeInput} onKeyUp={enterkey}/>
            <StyledIcon onClick={search_exec} ><FaSearch /></StyledIcon>
        </StyledSearchBar>
        </>
    )
}

export default SearchBar;


./Search/Search.js

  • useLocation 객체 생성하여 parameter값 확인
  • keyword text를 포함하는 데이터값을 필터링 하여 출력
//------------------------------ MODULE -------------------------------------
import styled from "styled-components";
import { Link, useLocation } from "react-router-dom";
import QueryString from 'qs';

//------------------------------ CSS ----------------------------------------
const StyledResult = styled.div`
    grid-column: 1 / span 4;
    height:50px;
    font-size : 20px;
`;
const StyledDiv = styled.div`
    width:320px;
    height:320px;
    padding:15px;
    text-align:center;
`;
const StyledImg = styled.img`
    width:220px;
    height:220px;
    padding:15px;    
`;
const StyledText = styled.div`
    font-size:8px;
    font-style:italic;
    font-weight:bold;
`;

//------------------------------ COMPONENT ----------------------------------
const Search = ({data}) => {
    const sdata = data.reduce((acc, cur) => acc.concat(cur));

    const location = useLocation();
    const params = QueryString.parse(location.search, { ignoreQueryPrefix: true });
    const keyword = params.keyword;

    const real_data = keyword ? sdata.filter((unit) => unit.name.includes(keyword)) : [];

    return (
        <>
            <StyledResult>{`Total: ${real_data.length}`}</StyledResult>
            {real_data.map((item, index) => {
                return (                    
                    <StyledDiv key={index}>
                        <Link to={`/Detail?id=${item.id}`}>
                            <StyledImg src = {item.thumbnail}></StyledImg>
                            <StyledText>Name : {item.name}</StyledText>
                            <StyledText>Price : {item.price}</StyledText>
                        </Link>
                    </StyledDiv>
                )
            })}
        </>
    )
}

export default Search;