[React] styled-components 재사용 및 CSS 함수 사용하기

jungmin Lee·2023년 7월 31일
0
post-thumbnail

업로드중..

팀 프로젝트가 블로그 사이트이며, CSS 작업이 비슷한 코드들을 작성할 필요가 있을 것으로 예상하였다. 우리 팀은 styled-components를 사용하여 재사용 가능한 컴포넌트를 작성하고, JavaScript 파일에 구현하여 코드를 재사용하기로 결정했다.

styled-components를 파일에 정의하고 내보내기

styled.js
styled-components로 작성한 코드들에서 재사용이 가능한 코드들은 styled.js 파일에 작성하고 필요한 파일에서 불러와서 사용할 수 있도록 작성했다. 그리고 InnerWrapper 컴포넌트는 조건에 따라 다른 스타일을 적용할 수 있도록 작성하였다. css 함수를 사용하여 조건부 스타일을 정의하고, 템플릿 리터럴 백틱 안에 작성하면 된다. TilWrapper 컴포넌트는 InnerWrapper 컴포넌트를 상속하고 필요한 CSS만 추가해주었다.

import styled, { css, keyframes } from 'styled-components';
import { NavLink } from 'react-router-dom';

export const Wrapper = styled.div`
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding-top: 64px;
`;

export const InnerWrapper = styled.div`
  /* 기본 InnerWrapper 스타일 */
  ${(props) =>
    !props.flex &&
    css`
      width: 1240px; /* 기본 컨텐츠영역 크기 */
      height: 100%;
      box-sizing: border-box;
      margin: 0 auto;
      padding: 80px 0;
    `}
  /* 헤더의 경우 InnerWrapper 스타일 */
  ${(props) =>
    props.flex &&
    css`
      width: 1240px;
      height: 100%;
      box-sizing: border-box;
      margin: 0 auto;
      display: flex;
      justify-content: space-between;
      align-items: center;
    `}
`;

export const TilWrapper = styled(InnerWrapper)`
  margin-top: 40px;
`;

HotTil.js
styled.js에 작성한 컴포넌트를 HotTil 파일에서 불러와서 사용했다. styled-components로 코드를 작성하면 바로 CSS 작업을 할 수 있다는 장점이 있지만, 파일안에서 코드가 길어지게 되고 다른 파일에 중복된 CSS 코드가 생기게 되는 점들을 styled.js 파일에서 불러오는 방법으로 보완할 수 있었다.

import '../../default/style.css';
// styled.js 파일에서 styled-components 
import { TilWrapper, TitleH1 } from '../../default/styled';
import HotTilNav from './component/HotTilNav';
import HotTilSwiper from './component/HotTilSwiper';
import TilList from './component/TilList';

function HotTil() {
  return (
    <div>
      <TilWrapper>
        <TitleH1>가장 인기있는 틸</TitleH1>
      </TilWrapper>
      <HotTilSwiper />
      <TilWrapper>
        <HotTilNav />
        <TilList />
      </TilWrapper>
    </div>
  );
}

export default HotTil;

Header.js
InnerWrapper flex를 작성하면 styled.js파일에 있는 InnerWrapper의 flex 조건부 스타일에 맞는 코드를 사용할 수 있다.

import { NavLink, Link } from 'react-router-dom';
import {
  HeaderWrapper,
  InnerWrapper,
  TextLogo,
  BtnGroup,
  HeaderLink,
  UserPic,
  TapMenu,
  TopNav,
  NavLogo,
} from '../default/styled';
import useStore from '../default/useStore';

function Header() {
  const { isLogin } = useStore();

  return (
    <HeaderWrapper>
      <InnerWrapper flex>
         {/* 코드 생략 */}
      </InnerWrapper>
    </HeaderWrapper>
  );
}

export default Header;

styled-components css함수 사용하기

버튼 스타일의 재사용성을 높이기 위해서 css 함수를 사용하여 버튼 스타일을 정의하였다. 정의한 버튼 스타일을 버튼 컴포넌트에 ${}로 불러와서 사용할 수 있었다.

import styled, { css } from 'styled-components';
/* 기본적인 버튼 스타일 */
const defaultBtnStyles = css`
  padding: 10px 16px;
  border-radius: 50px;
  transition: all 0.125s ease-in 0s;
`;

/* 버튼1 스타일 (css) */
const FilledBtnsStyle = css`
  /* 기본 버튼 스타일을 불러옵니다. */
  ${defaultBtnStyles}

  /* 여기 부터 추가 스타일 */
  background-color: var(--brand-color);
  color: white;
  &:hover {
    background-color: var(--color-darkgreen);
    color: var(--color-lightgreen);
  }
`;

/* 버튼2 스타일 (css) */
const OutlineBtnsStyle = css`
  /* 기본 버튼 스타일을 불러옵니다. */
  ${defaultBtnStyles}

  /* 여기 부터 추가 스타일 */
  color: var(--brand-color);
  border: 1px solid var(--brand-color);
  background-color: white;
  &:hover {
    background-color: var(--light-background-color);
    color: var(--brand-color);
  }
`;

/* <FilledBtns /> 형태로 사용하기 위한 코드 */
export const FilledBtns = styled.button`
  ${FilledBtnsStyle};
`;

/* <OutlineBtns /> 형태로 사용하기 위한 코드 */
export const OutlineBtns = styled.button`
  ${OutlineBtnsStyle};
`;

svg 이미지를 사용한 버튼 컴포넌트 만들기

import styled, { css } from 'styled-components';
import PreArrow from './image/preArrow.svg';
import PreArrowHover from './image/preArrowHover.svg';
import NextArrow from './image/nextArrow.svg';
import NextArrowHover from './image/nextArrowHover.svg';

export const PreNextButton = styled.button`
  background-size: cover;
  width: 35px;
  height: 35px;
  transition: background-image 0.3s ease;
  /* 이전 버튼 */
  ${(props) =>
    props.pre &&
    css`
      background-image: url(${PreArrow});
      &:hover {
        background-image: url(${PreArrowHover});
      }
    `}
  /* 다음 버튼 */
  ${(props) =>
    props.next &&
    css`
      background-image: url(${NextArrow});
      &:hover {
        background-image: url(${NextArrowHover});
      }
    `}
`;
profile
Leejungmin

0개의 댓글