---
# System prepended metadata

title: 20220207 Frontend 일일 개발일지
tags: ['20220207']

---

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에 영향을 끼칠 것이라 생각했다.
    
- 지금 작성하며 고민해보니 가능 할 것 같은 느낌이 들긴한다. 고민을 더 해봐야겠다.