본문 바로가기

배열로 렌더링 된 아이템 리스트 클릭 시 디테일 페이지에 정보 넘기기

codeConnection 2024. 6. 17.

상황

이런 식으로 데이터를 받아와 렌더링하는 배열이 있다.

이것을 클릭했을 때 디테일 페이지로 해당 아이템의 정보만 디테일 페이지로 넘기는 방법에 대해서 간단하게 알아 보겠다.

 

방식은 여러 가지가 있을 수 있다.

  1. 리스트가 렌더링 된 페이지에서 해당 아이템의 고유한 값(예를 들어 id 컬럼)을 URL 파라미터로 넘겨서 디테일 페이지에서 다시 fetch를 받은 뒤, 그 fetch 의 응답값을 다시 filter 하여 find 메서드로 id와 일치하는 값을 찾아오는 방법
  2. 필요한 정보가 리스트 렌더링 페이지에서 아이템에 다 담겨 있으니 그것을 그대로 디테일 페이지로 넘기는 방법

데이터가 여러 사람에 의해 실시간으로 변할 가능성이 있다면 1번의 방법이 좋겠고, 그럴 가능성이 적다면 굳이 디테일 페이지에서 한 번 더 fetch를 할 필요가 없으니 2번의 방법이 좋겠다.

방법

패키지 설치

yarn add react-router-dom

페이지 라우팅

디테일 페이지로 사용될 컴포넌트에 path 뒤에 :id를 붙인다.

라우팅 할 때 컴포넌트 import 하는 것 잊지 말자.

import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import SponsorList from './SponsorList';
import SponsorDetail from './SponsorDetail';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<SponsorList />} />
        <Route path="/detail/:id" element={<SponsorDetail />} /> {/* 아이디 부여 */}
      </Routes>
    </Router>
  );
}

export default App;

렌더링하는 컴포넌트에서 navigate 이벤트 핸들러 연결

본인은 item이라는 객체 안에 '번호'라는 한글로 된 컬럼이 있어서 저렇게 넘기고 있지만, 각 Item의 uuid나 id가 있는 경우에는 상황에 맞게 표기한다.

 

단 map문을 돌릴 때 최상단 태그에 부여하는 key와 일치해야 한다.

 

위까지는 공통이고 navigate 훅을 사용하는 부분에서 1, 2번 방식에서 차이가 있다.

 

이번에는 1번의 방법대로 새롭게 fetch해서 find 메서드로 찾아내는 방법을 작성해보겠다.

ID만 넘기고 find 메서드로 찾기

url 파라미터로 item의 key detail로 넘기기

import { useNavigate } from 'react-router-dom'; // useNavigate 훅 import

function SponsorList() {
	const naviagate = useNavigate();

	...
    
  return (
    <CenteredContainer>
      <Row className="justify-content-center">
        {filteredData.map((item, index) => (
          <Col key={item.번호} xs={12} sm={6} md={4} lg={3} className="mb-4"> {/* key와 일치 */}
            <StyledCard style={{ width: '18rem' }} onClick={() => navigate(`/sponsordetail/${item.번호}`)}> {/* key와 일치 */}
				...
            </StyledCard>
          </Col>
        ))}
      </Row>
    </CenteredContainer>
  );
}

디테일 페이지에서 받기

fetch받은 'data' 배열을 순회하면서 각 객체의 key 중 '번호'에 해당하는 값이
url 파라미터로 받은 'id'라는 값과 일치하는 것만 솎아 내서 새로운 하나의 아이템(객체)을 만들어 냄.

이 객체로 바인딩 할 것임.
주의할 점은 새로운 파라미터에서 받은 id는 문자열로 반환되기에 id를 정수로 바꿔주든지 item.id를 문자열로 바꿔주든지 해야 함.

import { useParams } from 'react-router-dom'; // useParams 훅이 필요함.
import { useQuery } from '@tanstack/react-query'; // 본인은 fetch를 TanStack Query로 이미 받았음


function SponsorDetail() {
	
    // useParams훅을 이용해서 url 파라미터에서 id를 가져옴.
    const { id } = useParams();
    
    // 데이터를 fetch 받거나 state 등으로 불러옴
    const { data } = useQuery({
        queryKey: ['data'],
    });

	// 데이터 배열에서 id와 내가 찾고자 하는 값과 일치하는 아이템을 찾아낸다.
    const sponsorData = data.find(item => item.번호.toString() === id);

    if (!sponsorData) {
        return <div>데이터를 찾을 수 없습니다.</div>;
    }

    return (
        <CardWrapper>
            <TopOfCard>
                <DonatorWrapper>
                    <Donator>{sponsorData.이름} <span style={{ color: 'black' }}>님</span></Donator>                    <ThanksMessage>따뜻한 후원 감사합니다.</ThanksMessage>
                </DonatorWrapper>
                <DonatorNumber>{sponsorData.후원번호}</DonatorNumber>
            </TopOfCard>
            <Amount>{sponsorData.절대값}원</Amount>
            <Thanks>소중한 후원 감사합니다.<br />보내주신 성원은 아이들을 위해<br />꼭 필요한 곳에 사용하겠습니다.</Thanks>
            <From>개인봉사자 드림</From>
        </CardWrapper>
    );
}

댓글