위코드 1차 팀프로젝트를 진행하며 정리한 내용입니다.
상단 카테고리를 선택해서 대분류 리스트 페이지를 보여주고 거기서 필터 버튼을 클릭하면 쿼리스트링을 추가해서 소분류가 되는 코드를 작성했습니다. 쿼리스트링 형식은 아래와 같습니다 .
category?category=main&id=1 // 대분류 보여주기, main 의 1번
category?category=main&id=1&color=2 // 컬러 분류 추가, main 의 1번의 컬러 1번 아이템들
에러가 났던 코드는 아래와 같습니다. 컬러 필터를 클릭해서 sortColor 함수를 실행하면 브라우저 url 주소 자체는 color=1, color=2 처럼 찍히지만, 실제 실행은 한칸 씩 밀리는 게 됩니다. (null, 1, 2 ,3 순으로 첫번 째 값이 null 로 찍힘)
function ProductList() {
const [products, setProducts] = useState([]);
const [searchParams, setSearchParams] = useSearchParams();
const category = searchParams.get('category');
const id = searchParams.get('id');
const color = searchParams.get('color'); // 여기서 없는 값을 가져오느라 null 이 찍힘
useEffect(() => {
fetch(`http://3.35.54.156:3000/category?category=${category}&id=${id}`)
.then(res => res.json())
.then(res => setProducts(res.getProducts));
}, [category, id]);
const sortColor = colorNum => {
searchParams.set('color', colorNum);
setSearchParams(searchParams);
fetch(
`http://3.35.54.156:3000/category?category=${category}&id=${id}&color=${color}`
)
.then(res => res.json())
.then(res => setProducts(res.getProducts));
};
..
sortColor 함수 안과 밖에서 콘솔을 찍어보면 fetch 함수 밖에서 선언된 color 의 첫 값으로 null 이 찍히는 것을 확인할 수 있었고, 최초 렌더링에서 color 에 찍힌 null 값이 sortColor 함수 내에 적용되는 것을 알 수 있었습니다. (전역변수라서 함수 내부에 영향을 줌) 그래서 아래와 같이 해당 변수 선언 자체를 color 쿼리스트링을 생성하는 sortColor 함수 안으로 옮겨서 문제를 해결했습니다.
function ProductList() {
const [products, setProducts] = useState([]);
const [searchParams, setSearchParams] = useSearchParams();
const category = searchParams.get('category');
const id = searchParams.get('id');
useEffect(() => {
fetch(`http://3.35.54.156:3000/category?category=${category}&id=${id}`)
.then(res => res.json())
.then(res => setProducts(res.getProducts));
}, [category, id]);
const sortColor = colorNum => {
searchParams.set('color', colorNum); // 여기서 추가하고
setSearchParams(searchParams);
const color = searchParams.get('color'); // 여기서 가져오는
fetch(
`http://3.35.54.156:3000/category?category=${category}&id=${id}&color=${color}`
)
.then(res => res.json())
.then(res => setProducts(res.getProducts));
};
..