본문 바로가기
💎 리액트

리액트 검색기능 구현 (스프링부트, 리액트 연동 쇼핑몰 검색 기능 구현)

by 비타민찌 2022. 3. 3.
728x90

스프링부트, 리액트 연동 쇼핑몰 검색 기능 구현

 

Header 페이지에서 검색 하면 -> ProductSearch 라는 새 페이지에서 검색 결과가 출력되는 검색 기능 구현.

백엔드 구현 부분은 이전 글을 참고해 주세요.

 

이전글 : 스프링부트 검색기능 구현

"test" 검색
 
 
1_ Header.js
function Header() {
  const [word, setWord] = useState("");

  const onSubmit = async () => {
    window.location.href = "/search/" + word;
  };

  return (
   <input
    onChange={(e) => {
    setWord(e.target.value);
    console.log(word);
    }}></input>

    <button
     type="button"
     onClick={() => {
     onSubmit();
     }}></button>
  );
}
 

 

 
input 으로 검색어를 입력하면 변경된 값을 감지하는 onChange 함수 안에서 setWord로 입력한 검색어인e.target.value를 word에 저장한다.
그리고 검색 버튼을 누르면 onSubmit 함수가 동작하여 "/search +검색어 word"로 새창 이동이 된다.
버튼 태그에 type="button"을 해주지 않으면 버튼을 누를 때마다 페이지 새로고침이 되기 때문에 꼭 해줘야 한다.

 

2_ Routing.js

class Routing extends React.Component {
  render() {
    return (
      <Router>
        <Routes>
          < 다른 링크들 ... />
          <Route path="/search/:word" element={<Search />} />
 

Routing.js 파일에서 "/search/:word" 로 Header.js 에서 전달한 word를 :으로 붙여준다.

 

 

3_ ProductSearch.js

검색어를 받아 띄워질 새 창인 ProductSearch.js 파일

import { useParams } from "react-router";

function Search() {
  const [searchData, setSearchData] = useState([]);
  const params = useParams();

  useEffect(() => {
    async function fetchData() {
      const result = await axios.get(
        "http://localhost:8080/product/search?word=" + params.word
      );
       console.log(result.data.result);
       setSearchData(result.data.result);
    }
    fetchData();
  }, []);
 

get 방식으로 받은 http://localhost:8080/product/search?word= 와 params.word를 합쳐 result에 저장, result에 담긴 데이터들을 setSearchData로 searchData에 저장한다.

이를 useEffect 함수에 만들어 컴포넌트가 렌더링 될 때마다 작업을 실행하게 한다.

 

전달한 word를 받기 위해 { useParams } from "react-router"를 import한다.

그리고 params.word 이렇게 꺼낸다.

 

console.log로 result.data.result를 출력해 함수 작동이 잘 되는지 확인해 보자.

값을 잘 받아오고 있다.

이제 이 결과를 화면에 출력해보자.

{searchData.map((product) => {
   return (
      <CardImg
      filename={product.filename.split(",")[0]}
      >/CardImg>
   );
})}
 

map 함수로 searchData에 저장된 값들을 하나씩 빼서 CardImg 태그에 담아 출력한다. (CardImg는 디자인을 적용한 div 태그)

처음엔 filename={product.filename} 이렇게만 했었는데 이렇게 했더니

한 상품에 이미지가 여러장이 저장된 경우 에러가 났다.

백엔드에서 첫번째 이미지만 가져오게 하거나, 프로필용 대표 사진을 따로 저장해서 그걸 가져오게 해도 되겠지만 일단은.. split 함수로 구분하여 첫번째 이미지만 보이게 처리했다.

 

 

 

728x90

댓글