프로젝트 노트 📝

[React][NHN] 다음 기사, 이전 기사의 제목을 띄워보고 페이지 이동시키기

수끼옹 2022. 11. 26. 17:23

이번 포스팅은 앞과 이어집니다.

 

기사 리스트를 클릭하면 그 기사에 맞는 세부페이지가 띄워지겠죠? 그런데 저는 여기서 또 다른 기능을 만들어보고 싶었습니다. 흔히 어떤 사이트의 보도자료 페이지를 보면 앞, 뒤 기사들로 이동할 수 있는 버튼이 있더라구요 저도 만들어보았습니다.

 

먼저 결과물입니다.

 

 

다음 글을 클릭하면 다음 기사로 넘어가고, 이전 기사를 누르면 이전 기사로 넘어갑니다. 단 첫 번째 기사와 마지막 기사는 이전 글과 다음 글이 없음을 알려줘야 합니다.

 

한번 살펴보겠습니다?


👉 원리

내가 들어온 기사의 id값을 이용하면 끝이다..!

이전 글은 id가 -1인 것의 페이지를 띄워주면 되고, 다음 글은 id + 1인 페이지를 띄워주면 됩니다.

 

👉 코드

[사용한 컴포넌트]

Detail.jsx, article.js(기사 구조체 작성)

 

먼저 article.js에 만들어 놓은 구조체 입니다.

// article.js
// summary와 content는 원하는 내용 넣으세요

export const articles = [
    {
        id: 1,
        title: "NHN 빅풋-위메이드, 'Project WEMIX Sports' 서비스 계약 체결",
        date: "2022.02.04",
        list: "NHN빅풋(대표 김상호)과 위메이드가 ‘Project WEMIX Sports(가칭)’ 게임의 서비스 계약을 체결했다. 이를 통해 양사는 NHN빅풋이 개발한 ‘Project WEMIX Sports’를 위메이드 자체 블록체인 플랫폼인 위믹스(WEMIX)에서 서비스...",
        summary: "...",
        image: "/img/article_photo1.png",
        content: "..."
    },
    {
    id: 2,
    title:
      "NHN빅풋, 위메이드와 ‘우파루 PROJECT(가칭)’ 위믹스 온보딩 계약 체결…P&E게임 라인업 확대",
    date: "2022.01.28",
    list: "NHN빅풋(대표 김상호)은 ‘WEMIX’ 플랫폼을 운영하는 위메이드(대표 장현국)와 ‘우파루 PROJECT(가칭)’ 게임의 온보딩 계약을 체결했다고 22일 밝혔다. ‘우파루 PROJECT’는 지난 2월에 서비스 계약을 체결한 ‘Project WEMIX Sports(가칭)’에 이어 위메이드와 손잡고 선보이는 두 번째 P&E 게임으로...",
    summary: "...",
    image: "/img/article_photo2.png",
    content: "..."
  },
  {
    id: 3,
    title: "NHN페이코, ‘페이코 자산관리’에 연말정산 점검 서비스 출시",
    date: "2022.01.28",
    list: "NHN페이코(대표 정연훈)는 마이데이터 기반 ‘페이코 자산관리’에 연말정산 점검 서비스를 출시했다고 28일 밝혔다. 페이코(PAYCO) 연말정산 점검 서비스는 ‘페이코 자산관리’에 연동된 연금계좌, 청약 저축, 보험 등 자산 데이터를 기반...",
    summary: "...",
    image: "/img/article_photo3.png",
    content: "..."
  },
  {
    id: 4,
    title:
      "‘페이코’ 복지 솔루션, 도입 기업 1,500개 돌파…복지 포인트·식권 직장인에 인기",
    date: "2022.01.28",
    list: "페이코(PAYCO)의 기업 복지 솔루션이 가파른 성장세를 타고 있다. NHN페이코는 지난해 페이코 식권, 상품권, 복지 포인트 등 페이코 복지 솔루션을 도입한 기업 수가 1,500개를 돌파했다고 8일 밝혔다. NHN페이코는 페이코 결제 사업 인프라와 플랫폼 운영 노하우를 접목해 기업 대상 복지 솔루션...",
    summary: "...",
    image: "/img/article_photo4.png",
    content: "..."
  },
  {
    id: 5,
    title: "NHN페이코, 설 맞이 GS25 ‘반값택배’ 할인 프로모션 진행",
    date: "2022.01.28",
    list: "NHN페이코(대표 정연훈)가 설 연휴를 맞아 GS25 ‘반값택배’ 할인 프로모션을 실시한다고 25일 밝혔다. `반값택배`는 GS25에서 GS25로 택배를 발송하고 수령하는 서비스로, 이용료가 기존 편의점 택배비의 절반 수준으로 저렴한 것이 장점이다. NHN페이코는 지난해 7월 GS네트웍스와 제휴를 통해 페이코...",
    summary: "...",
    image: "/img/article_photo5.png",
    content: "..."
  },
  {
    id: 6,
    title:
      "NHN 웹툰 서비스 ‘코미코’, 자체 제작 콘텐츠 확대하며 글로벌 공략 가속화",
    date: "2022.01.28",
    list: "NHN의 웹툰 서비스 '코미코(comico)가 자체 제작 콘텐츠를 확대하며 글로벌 시장 공략을 가속화 한다. NHN(대표 정우진)은 코미코 웹툰 제작 스튜디오를 설립하고 오리지널 웹툰을 포함해 100여 개의 작품을 자체 제작하고 있다고 25일 밝혔다. 신설...",
    summary: "...",
    image: "/img/article_photo6.png",
    content: "..."
  },
  {
    id: 7,
    title: "티켓링크, 뮤지컬 태양의 노래 예매 오픈",
    date: "2022.01.28",
    list: "NHN티켓링크(대표 왕문주)는 자사가 운영하는 티켓포털 티켓링크에서 뮤지컬 ‘태양의 노래’ 티켓 예매를 12일 오픈한다고 밝혔다. 티켓링크는 뮤지컬 ‘태양의 노래’ 티켓을 12일 오후 2시 티켓링크 홈페이지 및 모바일 앱에서 판매한다. VIP석은 14만원, R석은 12만원, S석은 8만원이며, 신용카드, 무통장입금...",
    summary: "...",
    image: "/img/article_photo7.png",
    content: "..."
  },
]

 

1. 먼저 버튼을 만들고 앞뒤 기사의 제목을 각각 띄워보겠습니다.

// Detail.jsx

<button></button> //이전 글로
<button></button> //다음 글로

 

버튼을 만들었다면, 이제 현재 페이지의 주소를 받아서 id값을 걸러낸 뒤, id-1과 id+1의 기사를 찾아서 변수에 넣어주면 됩니다.

//Detail.jsx

import { useNavigate, useSearchParams } from "react-router-dom";

const ArticleIn = () => {
	let navigate = useNavigate();
	const [searchParams] = useSearchParams();
	const id = Number(serchParams.get("id"));
	const prevArticle = articles.find((element)=>element.id === id-1)?.title;
	const nextArticle = articles.find((element)=>element.id === id+1)?.title;
    
	return(
    	<>
        
            ... //현재 페이지의 기사

            <button 
                    onClick={()=>navigate(`/article/detail?id=${id-1}`)}
                    disabled={!prevArticle}>
                    {prevArticle || "이전 글이 없습니다"}
            </button>
            <button 
                    onClick={()=>navigate(`/article/detail?id=${id+1}`)}
                    disabled={!nextArticle}>
                    {nextArticle || "다음 글이 없습니다"}
            </button>
        </>
    )
}

 

먼저 useSearchParams() 함수를 이용해 주소의 쿼리를 받아옵니다. 주소값은 언제나 문자열입니다. 우리는 id값을 -, + 해줘야 하기 때문에 Number()를 이용해 id를 숫자로 바꿔줘야 합니다.

 

현재 페이지의 id를 받아왔다면 articles(구조체)에서 현재 id값의 -1, +1된 기사를 find()로 찾아줍니다. '?' 의 의미는 값이 존재한다면~ 이란 뜻으로 여기서는 이전, 다음 기사가 존재한다면 title을 가져온다는 뜻이 됩니다. 값이 없다면 undefined를 반환합니다.

 

버튼에 onClick이벤트를 걸어서 이전, 다음 기사의 id를 넣어서 이동시키면 됩니다.

 

마지막으로 만약에 이전, 다음 글이 없다면 || 라는 연산자를 이용하면 됩니다. true일 때는 title을 띄워주는 것이고, false이면 글이 없다는 말을 띄워주는 것입니다.

 

또한 button에 disabled라는 속성을 넣어줘서 만약 이전글과 다음 글이 없는 상황. 즉 false인 상황이라면 버튼을 비활성화 시켜주면 됩니다.

 

 

끝!