💎 리액트

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

비타민찌 2022. 3. 3. 15:28
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