1편에 이어 간단하게 정리해 두려고 한다.
1. a tag 초기화
: css 초기화의 경우 일괄적으로 reset을 할 수 있는 코드 뭉치들이 있지만 일단 지금 단계에서는 user agent(브라우저)에서 어떤 세팅들이 있는지, 그게 내가 작성하고자 하는 레이아웃에 어떤 영향을 주는지 알고 싶어서 일괄 적용은 하지 않으면서 css를 작성해보고 있다.
a {
color: #292827; // theme color 등 원하는 색상 지정
text-decoration: none;
outline: none
}
a:hover, a:active {
color:#292827;
text-decoration: none;
}
2. div 태그 가운데 정렬
<div> 태그로 구분선(.divider)을 만들었다. 이제까지 가운데 정렬을 보통 margin: 0 auto 을 많이 썼는데 다른 margin 값이 이미 필요한 상황이어서 margin으로 가운데 정렬을 할 수 없었다. flex로 할 수도 있지만 text-align으로 가운데 정렬을 맞출 수 있는 방법도 있다.
해당 요소(.divider, 아래 예시에서 #child selector)에 test-align: center과 display: inline-block을 같이 적용해야 가운데 정렬이 될 것 같지만 그렇지 않다. 아래처럼 부모와 자식에 나눠서 속성을 적용해줘야 가운데 정렬이 적용된다. 왜 그런 건지 이유는 아직 모르겠다... css는 역시 어렵다...
#parent {
text-align: center;
}
// divider 요소
#child {
display: inline-block;
}
3. flex로 item 영역 크기 다르게 설정
부모 요소에 flex를 설정해서 아이템을 가로 정렬만 시켜놓은 다음 flex 관련 속성(justify-content, align-items, flex-grow 등)을 쓰지 않고, margin 값을 조절해서 원하는 영역 크기를 줄 수도 있다. margin-left: auto 를 주면 컨텐츠가 오른쪽 끝으로 쭉 밀려나게 된다는 점을 이용했다.
// html 마크업
<div class="container">
<svg class="icon"></svg>
<span>중요</span>
<span>{count.length}</span>
</div>
// css
.container {
display: flex;
}
.container > span:first-of-type {
margin-left: 16px;
}
.container > span:nth-of-type(2) {
margin-left: auto;
}
4. 라우터 분기에 따라 sidebar 메뉴의 배경 색상 다르게 주기
화면의 왼쪽 사이드바의 메뉴가 현재 중요, Today 두 개로 나뉘어져 있고, Today에 있는 전체 to do list 중에서 별표를 한 task만 중요 메뉴에서 보여지고 있다. 두 페이지의 화면 구성이 동일하다보니 상단의 title을 제대로 보지 않으면 내가 어느 페이지에 있는지 파악하기가 어려웠다. 내가 현재 있는 경로의 메뉴를 사이드바에서 배경 색상을 다르게 줘서 표시해주면 좋을 것 같았다.
tab 컴포넌트처럼 메뉴에 index를 줘서 현재 있는 위치를 상태값으로 관리하는 방법도 있겠지만, react-router-dom을 사용해 라우터 분기를 각각 /important 와 / 로 줬기 때문에 useLocation을 사용해 path 값을 가져와서 이를 이용해 배경 색상을 다르게 설정할 수도 있지 않을까 하는 생각이 들었다.
이 과정에서 현재 path 값과 라우터 분기의 일치 여부를 따져야 했기 때문에 sidebar 컴포넌트의 css를 styled-components로 리팩토링했다. props를 내려보내서 조건부 렌더링을 할 수 있다는 건 styled-components의 최대 장점이다.
import { Link, useLocation } from "react-router-dom";
import styled from "styled-components";
const StyledLink = styled(Link)`
background-color: ${(props) => props.path === props.to && "var(--bg-highlight)"};
`
export default function Sidebar() {
const { pathname: path } = useLocation();
return (
<Nav>
<StyledLink to="/important" path={path} />
<StyledLink to="/" path={path} />
</Nav>
);
}
최종적으로 위와 같은 코드를 작성할 수 있었는데 이 과정에서 새로 알게 된 점이 두 가지 있다.
1) styled()로 styled-components만이 아니라 react 컴포넌트도 전달할 수 있다.
styled-components의 장점으로 컴포넌트 재활용이 가능하다고 배우면서 styled() syntax를 배웠다. react-router-dom의 <Link /> 컴포넌트는 사실 a 태그지만 styled.a`` 로 styled-component를 만들 수는 없었다. 어떻게 해야하는지 고민하던 와중에 컴포넌트를 그 자체로 보낼 수 있다는 사실을 알게 되었다. 이렇게 해서 현재 경로의 path 값과 라우터 분기를 비교한 다음에 일치하면 highlight를 해줄 수 있었다.
2) css 변수를 그대로 속성값으로 사용할 수 있다.
highlight한 값을 이미 여러 군데서 쓰고 있어서 변수 설정을 해주었는데, styled-components에서도 사용자 지정 css 변수를 그대로 똑같이 쓸 수 있었다.
5. 아이콘 가져오기
bootstrap과 font-awesome 정도만 알고 있었는데, react icons도 있다는 걸 알게 되어서 사용해 봤다. 사용법은 다른 라이브러리와 크게 다르지 않다. 라이브러리를 설치하고, 사용하고 싶은 아이콘을 해당 컴포넌트에서 import로 불러와 사용하면 된다.
// Sidebar 컴포넌트
import { BsStar } from "react-icons/bs";
import { RxHamburgerMenu } from "react-icons/rx";
// 생략
return (
<Nav>
<StyledLink to="/important" path={path}>
<BsStar />
<span>중요</span>
<span>{count.length}</span>
</StyledLink>
<div className="divider"></div>
<StyledLink to="/" path={path}>
<RxHamburgerMenu />
<span>Today</span>
<span>{todos.length}</span>
</StyledLink>
</Nav>
);
아이콘 종류가 더 다양한 곳이 어디인지 등 각 라이브러리의 장단점과 특징을 언제 한 번 따로 찾아보긴 해야할 것 같다.
'배워서 남 주자' 카테고리의 다른 글
axios로 CRUD 요청하기 (0) | 2023.02.07 |
---|---|
배열 초기화: Array.fill()과 Array.from()의 차이 (0) | 2023.02.06 |
[알고리즘] 애너그램 걸러내기 (0) | 2023.02.04 |
substr(), substring(), slice() 차이 (1) | 2023.01.31 |
[React] 조건부 렌더링 (0) | 2023.01.30 |