초보 개발자의 성장 일기

styled-component를 이용하여 Grid, 페이지네이션 만들기 본문

Development/React JS

styled-component를 이용하여 Grid, 페이지네이션 만들기

YUNA 2023. 12. 8. 09:44

Grid

Flex와 비슷하지만 행과, 열 2차원 레이아웃을 담당한다.

display: flex;
grid-template-columns: 398px, 398px, 398px;
grid-column-gap: 19px;
grid-row-gap: 32px;

 

grid-template-columns는 세로로 몇개를 둘지, 한 개당 각각 column의 가로의 길이를 어떻게 설정할지 결정한다.

grid-column-gap은 각 아이템 사이 세로(열) 간격을 설정한다.

grid-column-gap은 각 아이템 사이  가로(행) 간격을 설정한다.

 

grid-template-columns: repeat(3, 398px);

repeat을 사용해서 398px을 3번 반복하도록 간결하게 나타낼 수 있다.

 

<TracksContainer>
  <TrackCard />
  <TrackCard />
  <TrackCard />
  <TrackCard />
  <TrackCard />
  <TrackCard />
</TracksContainer>

같은 컴포넌트가 반복이 되면 map함수를 이용해 나타낼 수 있다.

 

{Array(6).fill('').map((x, i) => {
	return <TrackCard key={`trackcard-${i}`}>
})}

Array(6).fill('') : 길이가 6인 배열이 만들어 지고 안의 엘리먼트는 빈 스트링이 들어 있다.

 

{Array(6).fill('').map((x, i) => 
	<TrackCard key={`trackcard-${i}`}>
)}

한문장으로 끝나는 함수는 return과 {}를 없애서 약어로 나타낼 수도 있다.

 

페이지네이션

const Container = styled.div`
`

const Button = styled.button`
`

우선 전체를 감쌀 div컨테이너와 button으로 빈 스타일 코드를 작성해준다.

 

export default function Pagination({ currPage, pageCount, onClickPage }) {
  return (
    <Container>
      {Array(pageCount)
        .fill('')
        .map((_, i) => {
          return <Button key={`pagination-button-${i+1}`}>{i+1}</Button>;
        })}
    </Container>
  );
}

currPage: 현재페이지

pageCount: 전체페이지 개수

 

페이지의 개수만큼 배열을 만들어주고 빈 스트링 값을 넣어준 후 map 함수를 이용해서 첫번째 인자값은 없고 두번째 인자값을 인덱스로 설정해서 버튼을 리턴해주면 된다. 여기서 인덱스 값으로 키값과 버튼을 만들어주면 되는데 0부터 시작하기때문에 +1을 해줘야 1부터 페이지네이션이 만들어진다.

 

 

이제 스타일을 넣어줄 차례다.

 

const Button = styled.button`
    font-size: 14px;
    line-height: 22px;
    text-align: center;
    color: #5E5F61;
    width: 22px;
    height: 22px;
    background: transparent;
	border-radius: 4px;

    + button {
        margin-left: 4px;
	}
`;

버튼을 클릭하지 않았을 때 스타일을 넣어준다.

 

<Button key={`pagination-button-${i}`} active={currPage === i}>

버튼을 클릭했을 때는 current페이지와 현재 페이지와 같을 때 활성화 할 active를 만들어준다.

 

${props => props.active && css`
    background-color: #524FA1;
    color: #F9FAFC;
`}

버튼 스타일 컴포넌트에 props를 사용해서 활성화 되었을 때 스타일을 추가한다.

 

이제 페이지네이션 버튼 앞뒤로 화살표 아이콘을 넣어주어야 한다.

import Arrow from './icons/Arrow.jsx';

우선 아이콘을 import 해 온다.

 

const ArrowButton = styled.button`
`;

스타일할 ArrowButton을 만들고 페이지네이션 버튼 앞뒤로 아이콘과 함께 감싸준다.

 

<ArrowButton>
	<Arrow />
</ArrowButton>
<ArrowButton flip>
	<Arrow />
</ArrowButton>

좌우 반전을 시켜주기 위해서 flip을 사용한다.

 

const ArrowButton = styled.button`
	margin: ${props => props.flip ? '0 0 0 16px !important': '0 16px 0 0'}

	${
      (props => props,
      flip &&
        css`
        transform: scaleX(-1)`)
    }
`;

그리고 props를 넣어주고 flip이 참일 때 css로 변환하도록 값을 넣어주면 된다.

 

const Container = styled.div`
    display: flex;
    align-items: center;
`;

가운데 정렬을 맞춰준다.

 

> svg {
    display: block
}

그리고 버튼의 아이콘에 block속성을 주면 가운데 정렬이 완성된다.

 

+: 셀렉터 결합자로, 형제 요소 중에서 바로 뒤에있는 첫번째 동생 요소를 선택한다.
>: 자식요소를 선택한다.

 

다음으로 화살표를 사용하지 못할 상황에 비활성화를 시켜주어야 한다.

 

<ArrowButton disabled={currentPage === 0}>

왼쪽 화살표는 현재 페이지가 0일 때 비활성화를 시켜준다.

 

<ArrowButton disabled={currentPage === pageCount}>

오른쪽 화살표는 페이지 개수와 같을 경우 비활성화를 시켜준다.

 

페이지 버튼이 항상 같은 개수만 보여주도록 만들어야 한다.

const [currPage, setCurrPage] = useState(0)

페이지 상태관리 코드를 작성해준다.

 

<Container>
      <Pagination currPage={currPage} onClick={setCurrPage}/>
</Container>

 

상태관리 코드를 페이지네이션에 전달해준다.

 

<Button 
    key={`pagination-button-${page}`}
    active={currPage === page}
    onClick={() => onClickPage(page)}
>

버튼에 onClick을 전달해 페이지를 누르면 해당 페이지가 실행되도록 함수를 넣어준다.

 

<ArrowButton
    disabled={currPage === 0}
    onClick={() => onClickPage(currPage - 1)}
>

왼쪽 화살표 버튼 아이콘에는 클릭시에 현재 페이지에서 -1로 이동하도록 해준다.

 

<ArrowButton
    disabled={currPage === 0}
    onClick={() => onClickPage(currPage + 1)}
>

오른쪽 화살표 버튼 아이콘에는 마찬가지로 +1을 해 주어야 한다.

 

function getPageNumbers(currPage, pageCount) {
  const resultPages = [];
  resultPages.push(currPage);

  let idx = 1;
  while (resultPages.length < 9) {
    if (currPage + idx < pageCount) resultPages.push(currPage + idx);
    if (currPage + idx > -1) resultPages.unshift(currPage - idx);
    idx++;
  }

  return resultPages;
}

페이지 길이가 9보다 클 경우 페이지 네이션이 9개만 나오도록 if문을 사용해준다.

 

#엘리스트랙 #엘리스트랙후기 #리액트네이티브강좌 #온라인코딩부트캠프 #온라인코딩학원 #프론트엔드학원 #개발자국비지원 #개발자부트캠프 #국비지원부트캠프 #프론트엔드국비지원 #React #Styledcomponent #React Router Dom #Redux #Typescript #Javascript