본문 바로가기
리액트 공부와 함께 하는 일상/3주차

[TIL] 3주차 - 4. Pagination / Lifiting-State-Up

by fefe94 2022. 1. 27.

1. Pagination : 다른 페이지를 보여줘! 

페이지 처리를 하는 방법은 크게 두가지가 있습니다.

 

 

 

이미지 출처 : https://uxplanet.org/ux-infinite-scrolling-vs-pagination-1030d29376f1

 

무한 스크롤방식

무한 스크롤 방식은 모바일에 적합합니다.

모바일 환경에서 콘텐츠를 보여주기에

가장 직관적이고 사용하기 쉬운 형식입니다.

사용자들이 직접 끊임없이 생성하는 콘텐츠가 많은

인스타그램, 유튜브 같은 소셜미디어가 이에 해당합니다.

 사이트와 앱에 적합합니다.

 

 

 

이미지 출처 : https://uxplanet.org/ux-infinite-scrolling-vs-pagination-1030d29376f1

 

일반적인 방식

일반적인 방식의 페이지 처리는 페이지 번호를 클릭해서

이동하는 방식의 페이지 처리 방법입니다.

사용자가 가야 할 방향이 뚜렷한, 목표지향적인

사이트와 앱에 적합합니다. 

 

 

 

이번시간에는 

일반적인 방식에 대해 알아보겠습니다.

 

  // startPage 는 항상 1 , 11 , 21 , 31 .. 식으로 
  // 1에서 10 씩 커지고 10 씩 작아지는 수이다! 
  // currentPage와는 다르다!!!

  // startPage는 시작페이지값을 알려주는 state이다.
  const [startPage, setStartPage] = useState(1);

  // 게시물 목록
  const { data, refetch } = useQuery(FETCH_BOARDS, { 
    variables: { page: startPage } 
  });

  // 페이징 처리 10개 씩
  const { data: dataBoardsCount } = useQuery(FETCH_BOARDS_COUNT )
  const lastPage = Math.ceil(dataBoardsCount?.fetchBoardsCount/10);

  // 페이지 네비게이션을 눌렀을 때 화면을 해당 페이지값으로 재구현 해줄 함수
  const onClickPage = (event) => {
    refetch({ page: Number(event.target.id) });
  };

  // 페이지 네비게이션 이전 목록
  const onClickPrevPage = () => {
     // 페이지가 0 이하로는 내려가지 않게 if문 처리. return은 함수 종료 시켜줌.
     if(startPage === 1) return; // <= 등호는 저렇게 해도 됨. 1보다 작을 일은 없겠지만...
     setStartPage(prev => prev - 10);
    //  refetch({ page: startPage - 10});
  }

  // 페이지 네비게이션 다음 목록
  const onClickNextPage = () => {
    // 시작페이지에 10 더한것이 마지막 페이지보다 크면 페이징 끝
    if(startPage + 10 > lastPage) return; 
    setStartPage(prev => prev +10);
    //  refetch({ page: startPage + 10});
  }

 

 

	<div>
      <h1>페이지네이션 연습!!!</h1>
      {/* map()을 사용해 데이터를 뿌려줄 리스트 생성 */}
      {data?.fetchBoards?.map((el) => (
        <div key={el._id}>
          {el.title} {el.writer}
        </div>
      ))}
      <span onClick={onClickPrevPage}>이전페이지</span>
      
      {/* 페이지 이동을 위한 네비게이션 생성 */}
      {new Array(10).fill(1).map(
        (_, index) => 
          index + startPage <= lastPage && (
            <span 
            key={index + startPage} 
            onClick={onClickPage} 
            id={String(index + startPage)}
            >
              {` ${index + startPage} `}
            </span>
          )
        )}

      <span onClick={onClickNextPage}>다음페이지</span>

    </div>

 


 

 

2. Lifting-State-Up : State 좀 나눠줘

 

React.js는 부모 컴포넌트에서 자식 컴포넌트로 전달하는 하향식, 단방향 데이터 흐름을 지향합니다. 덕분에 모든 Javascript 코드가 데이터에 집중되어 일관된 데이터 관리 로직을 가질 수 있습니다. 애플리케이션의 데이터를 관리하는 모델 컴포넌트가 있고 그 데이터를 UI컴포넌트에 전달하는 단순한 데이터 흐름이어서 코드의 흐름을 이해하고 관리하기 쉬운 애플리케이션을 만들 수 있다는 장점이 있습니다.

 

이미지 출처 :&nbsp;https://velog.io/@kyusung/React-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0

 

하지만 이러한 방식은 부모 컴포넌트에서 전달 받은 데이터의 형태나 타입만 알 수 있고, state에서 온건지 하드코딩으로 입력 받은 내용인지는 알 수 없다는 단점이 있습니다.

이 때 state 끌어올리기를 하면 자식 컴포넌트의 이벤트로 상위 컴포넌트의 상태를 바꾸어 줄 수 있습니다.

 

 

바로 상위 컴포넌트의 상태변경 함수를 하위 컴포넌트에 전달 시켜 실행시키는 것 입니다.

 

 

LifitingStateUpPage 부모 컴포넌트에서

count 변수와 onClickcounUP 함수를 만들고

Child1 Child2 자식 컴포넌트에 각각 전달합니다.

Child1 에서 카운트 버튼을 누르면

Child2 에서도 props로 공유 받은 count 값이 올라가게 됩니다.

 

 

꼭 부모 컴포넌트에서 전달해야 하는 것은 아닙니다.

Child1에서 상태변경 함수를 만들고 이를 부모 컴포넌트인 LiftingStateUpPage로 보내고

다시 여기서 Child2로 보낼 수도 있습니다.

 

자식1의 버튼을 누르면 자식2의 카운트도 동시에 올라가는 것을 확인할 수 있다.

 

 


Reference

 

댓글