백 개발자에게 1차개발 QA를 부탁했습니다. 자잘한 문제들은 쉽게 처리했지만, 아래 두 문제는 해결 과정을 남기는 것이 좋을 것 같아 정리합니다.
다른 것처럼 보이지만 사실 같은 기능의 문제입니다.
카테고리 클릭할 때 스타일이 변경되는 부분과 라우터를 컨트롤 하는 변수와 함수가 분리되어 있었습니다.
export default function MainDelay() {
const [isLoading, setIsLoading] = useState(true);
const [bookData, setBookData] = useState(null);
const [categoryName, setCategoryName] = useState("romance");
//fetch 부분 catergortName에 의존
useEffect(() => {
getBookCategory(categoryName)
.then((data) => {
setBookData(data);
return data.length;
})
.then((isComplete) => isComplete && setIsLoading(false));
}, [categoryName]);
return isLoading ? (
<Loading />
) : (
<Main setCategoryName={setCategoryName} bookData={bookData} />
);
}
function Main({ setCategoryName, bookData }) {
const navigator = useNavigate();
// 스타일 정하는 상태
const [click, setClick] = useState([true, false, false, false]);
//클릭 시 스타일 변경 및 카테고리 설정
const onClickCategory = (category, index) => {
setClick(() => {
const newArr = Array(4).fill(false);
newArr[index] = !newArr[index];
return newArr;
});
navigator(`/books?category=${category}`);
setCategoryName(category);
};
const onClickBook = (id) => {
navigator(`/books/${id}`);
};
return (
<div style={{ position: "relative" }}>
<CategoryNav onClickCategory={onClickCategory} click={click} />
<BannerSlide bookData={bookData} />
<NowBookList bookData={bookData} onClickBook={onClickBook} />
</div>
);
}
따라서 한 가지 변수에 기대게 하는 것이 옳다고 생각하였고, 그 기준을 라우터 주소로 잡았습니다.
라우터 주소로 잡은 이유는 뒤로가기, 새로고침 시 라우터 주소는 잘 유지되기 때문이었습니다.
두번째로, 어차피 첫 렌더링 때 한 개의 카테고리 페이지를 보여주니 초기 라우터 값을 로맨스로 고정하였습니다.
export default function MainDelay() {
const { search } = useLocation(); //라우터 주소 가져오기
// 라우터 주소에서 카테고리 부분만 빼서 스티링을 리턴하는 함수
const selectCategorySearch = () => {
let index = search.indexOf("=");
let category = search.slice(index + 1);
return category;
};
const [isLoading, setIsLoading] = useState(true);
const [bookData, setBookData] = useState(null);
//라우터에 따라 상태가 달라진다
const [categoryName, setCategoryName] = useState(selectCategorySearch());
//라우터가 바뀔때마다 상태도 변경시켜주도록
useEffect(() => {
setCategoryName(selectCategorySearch());
}, [search]);
//비동기처리 및 에러 핸들링
useEffect(() => {
const renderCategory = async () => {
try {
const data = await getBookCategory(categoryName);
if (data.message) throw new Error(data.message);
setBookData(data);
setIsLoading(false);
} catch (err) {
console.log(err);
}
};
renderCategory();
}, [categoryName]);
return isLoading ? (
<Loading />
) : (
<Main
categoryName={categoryName}
setCategoryName={setCategoryName}
bookData={bookData}
/>
);
}
function Main({ categoryName, setCategoryName, bookData }) {
const navigator = useNavigate();
// 카테고리 클릭시 라우터 이동
const onClickCategory = (category) => {
navigator(`/books?category=${category}`);
};
const onClickBook = (id) => {
navigator(`/books/${id}`);
};
return (
<div style={{ position: "relative" }}>
<CategoryNav
onClickCategory={onClickCategory}
categoryName={categoryName}
/>
<BannerSlide bookData={bookData} />
<NowBookList bookData={bookData} onClickBook={onClickBook} />
</div>
);
}
이렇게 하여서 라우터가 바뀌는 것에 의존하게 되었다. 흐름도 깔끔하고, 카테고리가 추가되었을때 수정 전 코드는 click state를 변경해줘야하는 것에 비해 이 코드는 그럴 필요가 없다. 재사용성이 높아졌다!