홈페이지 검색창에 검색어를 입력 후 검색 버튼을 클릭할 경우
ProductList페이지로 이동하여 검색 결과를 출력하도록 함
Navbar.jsx
useState 로 search를 추가한다.
검색창(input)의 내용이 변경될 때마다 setSearch로 검색어를 저장한다.
그리고 onSubmit 이벤트로 검색 버튼을 클릭할 경우
handleSubmit을 실행하여
검색어가 공백이 아닐 경우에만 navigate를 사용해 products로 이동한다.
파라미터로는 search= 검색어에 공백을 제거해서 보낸다.
const Navbar = ({ user, cartCount }) => {
const [search, setSearch] = useState(""); //검색어
const navigate = useNavigate();
// 검색 버튼 클릭 시 실행
// 검색어가 공백이면 실행안되게 하며, 검색어가 있을 경우 공백 제거 후 동작
const handleSubmit = (e) => {
e.preventDefault();
if (search.trim() !== "") {
navigate(`/products?search=${search.trim()}`);
}
};
return (
<nav className="align_center navbar">
<div className="align_center">
<h1 className="navbar_heading">myCart</h1>
<form onSubmit={handleSubmit} className="align_center navbar_form">
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
className="navbar_search"
placeholder="제품 찾기..."
/>
<button type="submit" className="search_button">
검색하기
</button>
</form>
</div>
ProductsPage.jsx에서 검색어를 파라미터로 받아서 사용할거다.
searchQuery 로 search 파라미터를 받아온다.
그리고 useData로 데이터를 받아올 때 검색어를 파라미터로 추가하여서 보내고
[searchQuery]가 변경되면 실행되게끔 추가한다.
const ProductsList = () => {
//sidebar에서 카테고리 쿼리스트링을 받아온다.
const [search, setSearch] = useSearchParams();
const category = search.get("category"); //모든 쿼리스트링 중 카테고리
const searchQuery = search.get("search"); //검색창에서 검색어 가져오기
const page = search.get("page");
//useDate(url)이 들어가야함
//결과(res)는 categories와, error에 담는다.
const { data, error, isLoading } = useData(
"/products",
{
params: {
search: searchQuery, //검색어 추가
category, //카테고리 파라미터 전달
page, //페이지 추가(페이지네이션 사용)
},
},
[searchQuery, category, page]
);
ProductsList.jsx
상품 리스트 페이지에 정렬 옵션을 추가할거임
정렬 방법과 정렬 결과를 관리할 useState를 추가한다.
const ProductsList = () => {
const [sortBy, setSortBy] = useState(""); //정렬 방법
const [sortedProducts, setSortedProducts] = useState([]); //정렬 결과
그리고 select 태그에 onChange 이벤트로
select의 옵션이 변경될 때 마다 setSortBy 에 바뀐 정렬 옵션을 저장한다.
<h2>상품목록</h2>
<select
onChange={(e) => setSortBy(e.target.value)}
name="sort"
id=""
className="products_sorting"
>
<option value="">정렬방법</option>
<option value="price desc">가격높은순</option>
<option value="price asc">가격낮은순</option>
<option value="rate desc">평점높은순</option>
<option value="rate asc">평점낮은순</option>
</select>
//정렬하기
useEffect(() => {
//데이터와 데이터 안의 제품이 있을 경우(useData의 결과)
if (data && data.products) {
// 데이터의 products를 복사하여 products함수에 담는다.
const products = [...data.products];
if (sortBy === "price desc") {
//sortBy(정렬 옵션)이 가격 내림차순
setSortedProducts(products.sort((a, b) => b.price - a.price));
} else if (sortBy === "price asc") {
//sortBy(정렬 옵션)이 가격 오름차순
setSortedProducts(products.sort((a, b) => a.price - b.price));
} else if (sortBy === "rate desc") {
//sortBy(정렬 옵션)이 평점 내림차순
setSortedProducts(
products.sort((a, b) => b.reviews.rate - a.reviews.rate)
);
} else if (sortBy === "rate asc") {
//sortBy(정렬 옵션)이 평점 오름차순
setSortedProducts(
products.sort((a, b) => a.reviews.rate - b.reviews.rate)
);
} else {
//정렬 옵션이 그 외의 경우 (default)
setSortedProducts(products);
}
}
}, [sortBy, data]); //정렬방법과 데이터가 바뀔 때 마다 실행
products.sort((a,b) => b.price = a.price));
((a,b) => b.price = a.price)); 이 부분이 정렬 조건임
b의 가격에서 a의 가격을 마이너스 했을 때 참이면 앞에 온다.
https://hianna.tistory.com/409
[Javascript] 배열 정렬하기 (오름차순, 내림차순, 문자열, 객체)
배열 정렬하기 (오름차순, 내림차순, 문자열, 객체) 1. sort() 함수 2. sort() 함수로 숫자 오름차순 정렬하기 3. sort() 함수로 숫자 내림차순 정렬하기 4. sort() 함수로 문자열 정렬하기 5. sort() 함수로
hianna.tistory.com
그리고 정렬된 결과를 반복문으로 출력한다.
{/* products가 있을 경우 반복문으로 출력 */}
{data.products &&
sortedProducts.map((product) => (
<ProductCard key={product._id} product={product} />
))}
1. default
2. 가격 높은 순
3. 평점 낮은 순
\
등 정렬이 가능하다.
하지만 여기서 문제는...
이 정렬이 각 페이지에서만 가능하다는 점
이 부분의 개선이 필요하다
useEffect(() => {
if (user) getCart(); // 유저가 바뀌거나 시작 시 카트 정보 가져온다.
}, [user]);