20220207 Frontend 일일 개발일지 === ###### tags: `20220207` # 개발 내용 ## 로딩시 리렌더링 되는 문제 해결. :::warning 뭔가 SHOP 화면에서 필터링 적용하여 렌더링 시 2번 3번 렌더링 되는 이슈가 있었다. 또한, 홈화면에서 브랜드를 눌렀을때 `/search?keyword=${검색어}` 로 이동했다가, 다시 `/search` 로 이동하는 버그가 있었다. ==바로 검색되는 `/search?keyword=${검색어}`로 가는것이 정상이였지만 말이다.== ::: - ShopTemplate 화면에서, ```typescript= useEffect(() => { const query = queryMaker( filteredCategory, filteredBrand.map((brand) => brandId.get(brand)), filteredCollections, filteredGender, filteredPrice, sortOption, ); router && router.push({ pathname: "/search", query: query, }); }, [ luxaryFilter, filteredCategory, filteredBrand, filteredGender, filteredPrice, sortOption, brandId, ]); ``` 해당 코드를 통해 필터가 적용되면 `router.push` 를 통해 필터를 적용했다. #### 문제점이라고 생각한 이유 `/search?keyword=${검색어}`로 이동했을때, 해당 `useEffect`는 무조건 작용하는 것으로 보여졌다. -> `query` 객체가 비어있을텐데, 불필요하게 해당 `push` 가 작동하는 것이였다. #### 바꾼 코드 ```typescript= useEffect(() => { const query = queryMaker( filteredCategory, filteredBrand.map((brand) => brandId.get(brand)), filteredCollections, filteredGender, filteredPrice, sortOption, ); Object.keys(query).length > 0 && router && router.push({ pathname: "/search", query: query, }); }, [ luxaryFilter, filteredCategory, filteredBrand, filteredGender, filteredPrice, sortOption, brandId, ]); ``` - 간단하게 `query` 객체가 빈 객체가 아닐때 작동하도록 수정하였고, 버그 수정했다. --- ## 드롭다운 박스 `z-index` 관련 문제 해결 작일 `z-index: -1` 로 주어서 해결했지만, 다른 문제가 기다리고 있었다. #### 문제점 ![](https://i.imgur.com/koUzwls.png) 위와 같이 왼쪽에 잘린 상품 그리드에 전체에 `z-index`를 -1로 주었더니, - 상품 이미지 클릭 불가 - 상품 하단 찜 클릭 불가 ==아예 싹다 클릭이 불가능했다..== #### 해결방법 ```typescript= return ( <> <SortContent onClick={() => setIsShow(!isShow)}> {currentSort} </SortContent> {isShow && ( <StyledDropdownWrapper onClick={() => setIsShow(false)}> <DropdownParent> <DropdownMenu show={isShow} scrolled={scrolled}> {contents.map((content) => ( <DropdownItem active={content === currentSort} key={content} onClick={() => onHandleCurrentSort(content)} > <MainText>{content}</MainText> <SubText>{subContents[content]}</SubText> </DropdownItem> ))} </DropdownMenu> </DropdownParent> </StyledDropdownWrapper> )} </> ); ``` - 위 컴포넌트가 `Dropdown` 컴포넌트인데, 해당 컴포넌트의 `StyledDropdownWrapper`에 `z-index`를 추가하였다. ```typescript= const StyledDropdownWrapper = styled.div` position: fixed; top: 0; right: 0; width: 100%; height: 100%; z-index: 100; `; ``` - `StyledDropdownWrapper` 는 드롭다운이 활성화 되었을때의 드롭다운 바깥 전체 컴포넌트인데, 해당 컴포넌트에게 `z-index` 속성을 추가하여 해결하였다. --- ## 로딩 컴포넌트 추가 ### react-loader-spinner 라이브러리를 활용하였다. #### 왜 해당 라이브러리를 사용하였는가? - 굳이 스피너를 만들 필요성도 없거니와 로딩 스켈레톤을 사용할 로딩 상태를 판단하는 것이 더 중요하다고 생각하여 외부 라이브러리를 사용하였다. - `SWR` 를 활용하는 입장에서는 로딩 상태를 판별하는 것이 굉장히 용이하다. - 이 이유가 `swr`를 선택한 이유기도 하였다. ```typescript= const {data, error} = useSWR('END_POINT', fetcher); ``` - 위와 같은 코드가 있을때, data값이 false라면 로딩 상태임을 공식문서로 확인 할 수 있다. - 따라서 필요한 코드는 아래처럼 간단하다. ```typescript= if(!data) { return (<Loading />) } ``` - 단, 위와 같은 코드는 최종 `return` 바로 위에 작성되어야 함을 주의하였다. --- ## 홈 화면 내 찜 아이콘 선택시 버블링 문제 해결. > 아주 간단한 버그를 해결했다. ```typescript= const ProductThumbnailImage: FunctionComponent<ProductThumbnailImageProps> = ( props, ) => { const { imgSrc, backgroundColor, isInWishList, onHandleWishClick } = props; const onClick = (e) => { e.preventDefault(); onHandleWishClick(); }; return ( <ProductThumbnailImageWrapper> {isInWishList ? ( <Icon onClick={onClick} name="BookmarkFilled" style={{ cursor: "pointer", maxWidth: "15px", minWidth: "15px" }} /> ) : ( <Icon onClick={onClick} name="Bookmark" style={{ cursor: "pointer", maxWidth: "15px", minWidth: "15px" }} /> )} <ProductImage src={imgSrc} category="home" backgroundColor={backgroundColor} /> </ProductThumbnailImageWrapper> ); }; ``` - `Icon`에 할당되었던 `onClick` 함수에 `e.preventDefault` 추가로 버블링을 억제하였다~ --- ## 검색 기능 활성화 #### 개발 방법 ```typescript= <Icon name="Magnifier" style={{ cursor: "pointer" }} onClick={() => { Swal.fire({ position: "top", padding: "1rem", width: "70%", icon: "question", titleText: "검색어를 입력하세요. 🧐", input: "text", inputAttributes: { autocapitalize: "off", }, showCancelButton: true, confirmButtonText: "검색", confirmButtonColor: "black", cancelButtonText: "취소", cancelButtonColor: "#909090", showLoaderOnConfirm: true, preConfirm: (input) => { router && router.push({ pathname: "search", query: { keyword: `${input}`, }, }); }, }); }} /> ``` - `HeaderMain` 컴포넌트의 돋보기 아이콘에 해당 코드만 추가하였다. - 너무 쉽게 완료되어서.. 고민이다. #### 고민사항 - 왜 굳이 외부 라이브러리로 이를 구현했는가? - 모달을 이미 작성한 상태에서 다른 형식의 모달을 작성하는것이 현실적인 프로젝트 deadline에 영향을 끼칠 것이라 생각했다. - 지금 작성하며 고민해보니 가능 할 것 같은 느낌이 들긴한다. 고민을 더 해봐야겠다.