
개인 프로젝트로 진행했던 마켓제로 쇼핑몰을 리팩토링 하면서 검색 페이지에서 아주 조금? 은 아닌것 같고 꽤 헤맸던것 같다.
이유는 기존에 키워드를 다루는 상태가 너무 중구난방으로 중복되고 필요 이상으로 복잡하게 쓰이면서 계속 꼬였던게 문제였다.
/search?keyword=${encodeURIComponent(keyword)});문제점!
searchKeyword 상태가 애플리케이션의 여러 부분에서 다루어지고 있었다는 점setSearchKeyword 를 통해 상태를 설정하고, 이 상태를 SearchList 컴포넌트에 prop으로 전달하여 사용하고 있었다.해결방안!
useLocation 훅을 사용하여 SearchList 컴포넌트에서 직접 검색어를 가져오는 방식으로 코드를 수정
const SearchBar = () => {
const navigate = useNavigate();
const handleSubmit = (e) => {
e.preventDefault();
if (keyword.trim() !== '') {
navigate(`/search?keyword=${encodeURIComponent(keyword)}`);
setShowModal(false);
}
};
const handleKeyPress = (e) => {
if (e.key === 'Enter' && keyword.trim() !== '') {
navigate(`/search?keyword=${encodeURIComponent(keyword)}`);
setShowModal(false);
}
};
export default SearchBar;
먼저, 검색바에서 검색어를 입력하거나 Enter를 눌러 검색할 때,
navigate 함수를 이용하여 검색 페이지로 이동하고, 이때 URL의 쿼리 파라미터로 keyword를 포함시킨다.
import { Link, useLocation } from 'react-router-dom';
const SearchList = () => {
const location = useLocation();
const searchKeyword =
new URLSearchParams(location.search).get('keyword') || '';
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('/data/products.json');
const data = await response.json();
setAllProducts(data.allProducts);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
// 검색 키워드에 따른 상품 필터링
useEffect(() => {
let filteredProducts;
if (searchKeyword !== '') {
filteredProducts = allProducts.filter((product) =>
product.productName.toLowerCase().includes(searchKeyword.toLowerCase()),
);
} else {
filteredProducts = allProducts;
}
setSearchResult(filteredProducts);
setCurrentPage(1); // 검색 키워드가 변경되면 첫 번째 페이지로 리셋
}, [searchKeyword, allProducts]);
searchList 검색결과 페이지에서는 useLocation을 사용하여 URL의 위치를 가져온다.
위 코드에서 new URLSearchParams(location.search).get('keyword') || ''; 코드는 URL의 쿼리 파라미터에서 'keyword' 값을 가져오는 역할을 한다.
즉, searchKeyword는 URL의 검색 쿼리에서 'keyword'를 가져온다.
이렇게 가져온 'keyword' 값은 searchKeyword 상태에 저장되며,
이후 useEffect에서 allProducts를 필터링하는 데 사용된다.
그리고 현재 페이지를 1로 설정하여, 검색 결과가 변경되면 항상 첫 페이지부터 보여주게 한다.


리팩토링 계획이었던 상태관리나 메인, 로그인 시 유저 이름 업데이트, 장바구니와 위시리스트 등등 거의 모든 부분들을 수정했다.
완벽하진 않지만, 마무리가 잘 된것 같고 아직 필터링 하는 부분에서 살짝 고쳐야할 부분이 있긴 하지만 그래도 트러블슈팅 과정이 잘 해결되었다는거로 만족합니다.