Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발공부일지

[react-project] Search Bar 만들기 본문

Project

[react-project] Search Bar 만들기

보람- 2023. 12. 20. 14:15

** SearchBar component

const SearchBar = ({ handleSearch }) => {
  const [searchQuery, setSearchQuery] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    handleSearch(searchQuery);
  };

  return (
    <form
      onSubmit={handleSubmit}
      className="border border-solid border-gray-300 rounded-lg w-[300px] h-[35px] flex items-center "
    >
      <input
        required
        onChange={(e) => setSearchQuery(e.target.value)}
        type="text"
        placeholder={"Search..."}
        className="border-none w-[90%] pl-2"
      />
      <button className="w-[10%]">
        <img src={Search_icon} alt="" className="w-[60%] " />
      </button>
    </form>
  );
};

- input에 작성하고, 값을 setSearchQuery에 담고(onChange)

- onsubmit에 handleSubmit 함수를 만들어서 preventDefault()로 막고 header에 받은 handleSearch에 searchQuery를 담기

 

 

 

** Header component

const Header = () => {
  const navigate = useNavigate();
  
  const handleSearch = async (query) => {
    try {
      const response = await axios(
        `${process.env.REACT_APP_API_SERVER}/search/1?q=${query}`
      );
      console.log(response.data);
      navigate(`/search/1?q=${encodeURIComponent(query)}`);
    } catch (error) {
      console.log(`error :`, error);
    }
  };

  return (
    <>
      <div className="sticky top-0 w-[100%] h-[80px] border-b flex flex-row items-center justify-center z-30 bg-white">
        <div className="w-[40%] flex flex-row items-center justify-around">
          <Link to={"/"} className="font-logo text-4xl text-accent-blue ">
            Stacker-Labs
          </Link>
          <SearchBar handleSearch={handleSearch} />
        </div>
      </div>
    </>
  );
};

- header안에서 검색하는 searchBar component를 넣어주기

- handleSearch 함수를 만들어서 query를 담아 navigate를 사용해서 search페이지로 이동

 

 

 

** Search page

const Search = () => {
  const location = useLocation();
  const queryParams = new URLSearchParams(location.search);

  const [searchQuery, setSearchQuery] = useState("");
  const [searchBoard, setSearchBoard] = useState([]);

  useEffect(() => {
    const result = async () => {
      try {
        const queryValue = queryParams.get("q");
        setSearchQuery(queryValue);
        console.log(queryParams.get("q"));
        const response = await axios.get(
          `${process.env.REACT_APP_API_SERVER}/search/1?q=${queryValue}`
        );
        console.log(
          `${process.env.REACT_APP_API_SERVER}/search/1?q=${queryValue}`
        );
        setSearchBoard(response.data.boards);
        setPage(response.data.nextPage);
      } catch (error) {
        console.log(`error :`, error);
      }
    };

    if (queryParams.get("q") !== searchQuery) {
      result();
    }
   
  }, [searchQuery, queryParams]);

  return (
    <>
      <div className=" w-7/12 mx-auto py-5 font-serif flex justify-between items-center">
        <div className="text-3xl">Search results for {searchQuery} </div>   
      </div>
    </>
  );
};

- useLocation과 URLSearchParams로 query를 꺼내서 서버에 요청하기

- 검색된 결과물들을 search페이지에 보여주기

- url에서 query가 바뀐다면 다시 useEffect가 실행되도록 인자에 넣어주기

 

 

 

 

 

 

*** useHistory의 push 메서드와 React Router의 Navigate 컴포넌트

 


** useHistory의 push 메서드

 

- 함수 컴포넌트 내부에서 직접 호출할 수 있음
- 특정 이벤트나 상태에 따라 동적으로 페이지를 이동할때 사용함

 

import { useHistory } from 'react-router-dom';

const YourComponent = () => {
  const history = useHistory();

  const handleButtonClick = () => {
    history.push('/new-page');
  };

  return (
    <button onClick={handleButtonClick}>Go to New Page</button>
  );
};

 



** Navigate 컴포넌트


- JSX 코드에서 페이지 이동할때 사용함

import { Navigate } from 'react-router-dom';

const YourComponent = () => {
  // 조건에 따라 페이지 이동 여부를 결정
  const shouldNavigate = true;

  return shouldNavigate ? <Navigate to="/new-page" /> : <div>Not Navigating</div>;
};



** 이벤트 핸들러에서 동적으로 페이지를 이동할 때는 useHistory의 push 메서드를 사용

** JSX 코드 내에서 조건에 따라 페이지 이동할 때는 Navigate 컴포넌트를 사용

 

 

 

 


 encodeURIComponent

 

- navigate 함수를 사용하여 /search/1?q=${encodeURIComponent(query)}로 이동할때
- query는 사용자가 검색한 쿼리를 나타내고

- encodeURIComponent 함수를 사용하여 쿼리 문자열을 URI로 인코딩

   →  URI에 특수 문자가 포함될 수 있기 때문에 안전하게 전달하기 위해 

- 예를 들어 "react" 라고입력했다면 →    /search/1?q=react 



※ useLocation, URLSearchParams

const location = useLocation();
const queryParams = new URLSearchParams(location.search);
const queryValue = queryParams.get("q");

 

- useLocation 은 현재 url의 정보를 가져오는데, 이정보에 query가있음

- URLSearchParams에 location.search를 queryParams에 담아서 query를 꺼내올수있다.

  → ( URLSearchParams는 URL의 쿼리 문자열을 다루기 위한 객체이며, 현재 URL의 쿼리 문자열을 이용하여 queryParams 객체를 생성한다.)

 

- 예를들어 /search/1?q=react 이라면 queryParams.get("q")를 queryValue에 담아 console 을 찍으면 react가 나온다.