개발/Front

[React] react-router-dom v6 : url에 parameter 사용하기

코드아키택트 2022. 1. 18. 19:26
반응형

안녕하세요 갈아만든쌀 입니다. 오늘은 React이야기. 맨 아래 깃허브 링크도 추가하였습니다

적용 가능 시나리오

  • 상품 디테일 보기

특정 메뉴를 보고 그 상세내용을 확인하는 시나리오에 사용가능. 왼쪽은 ~/menu. 오른쪽은~/menu/0으로 됨. comment 가 많이 좁지만 무시하도록 하자

키 컴포넌트

import {Link, useParams} from 'react-router-dom'

흐름 및 주요 부분 설명

dishes.js / comments.js -> MainComponent.js 중 <Route path="/menu/:dishId"~/> -> DishdetailComponent.js

코세라 풀스텍 강의 중 일부입니다.

dishes.js 및 comments.js에는 json형식으로 데이터를 담고 있습니다. 이 데이터를 MainComponent.js에 임포트한 후 state에 담습니다. state에 담긴 위 두 정보를 DishdetailCompont에 통째로 넘깁니다. 

 이후 DishdetailComponent안에서 dishId에 맞는 정보만 filter합니다

 

이용할 데이터

export const DISHES =
    [
        {
        id: 0,
        name:'Uthappizza',
        image: '/assets/images/uthappizza.png',
        category: 'mains',
        label:'Hot',
        price:'4.99',
        featured: true,
        description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.'                    
        },
        {
        id: 1,
        name:'Zucchipakoda',
        image: '/assets/images/zucchipakoda.png',
        category: 'appetizer',
        label:'',
        price:'1.99',
        featured: false,
        description:'Deep fried Zucchini coated with mildly spiced Chickpea flour batter accompanied with a sweet-tangy tamarind sauce'
        },
        {
        id: 2,
        name:'Vadonut',
        image: '/assets/images/vadonut.png',
        category: 'appetizer',
        label:'New',
        price:'1.99',
        featured: false,
        description:'A quintessential ConFusion experience, is it a vada or is it a donut?'
        },
        {
        id: 3,
        name:'ElaiCheese Cake',
        image: '/assets/images/elaicheesecake.png',
        category: 'dessert',
        label:'',
        price:'2.99',
        featured: false,
        description:'A delectable, semi-sweet New York Style Cheese Cake, with Graham cracker crust and spiced with Indian cardamoms'
        }
    ];

▶︎ dishes.js

export const COMMENTS = 
[
    {
        id: 0,
        dishId: 0,
        rating: 5,
        comment: "Imagine all the eatables, living in conFusion!",
        author: "John Lemon",
        date: "2012-10-16T17:57:28.556094Z"
    },
    {
        id: 1,
        dishId: 0,
        rating: 4,
        comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
        author: "Paul McVites",
        date: "2014-09-05T17:57:28.556094Z"
    },
    {
        id: 2,
        dishId: 0,
        rating: 3,
        comment: "Eat it, just eat it!",
        author: "Michael Jaikishan",
        date: "2015-02-13T17:57:28.556094Z"
    },
    {
        id: 3,
        dishId: 0,
        rating: 4,
        comment: "Ultimate, Reaching for the stars!",
        author: "Ringo Starry",
        date: "2013-12-02T17:57:28.556094Z"
    },
    {
        id: 4,
        dishId: 0,
        rating: 2,
        comment: "It's your birthday, we're gonna party!",
        author: "25 Cent",
        date: "2011-12-02T17:57:28.556094Z"
    },
    {
        id: 5,
        dishId: 1,
        rating: 5,
        comment: "Imagine all the eatables, living in conFusion!",
        author: "John Lemon",
        date: "2012-10-16T17:57:28.556094Z"
    },
    {
        id: 6,
        dishId: 1,
        rating: 4,
        comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
        author: "Paul McVites",
        date: "2014-09-05T17:57:28.556094Z"
    },
    {
        id: 7,
        dishId: 1,
        rating: 3,
        comment: "Eat it, just eat it!",
        author: "Michael Jaikishan",
        date: "2015-02-13T17:57:28.556094Z"
    },
    {
        id: 8,
        dishId: 1,
        rating: 4,
        comment: "Ultimate, Reaching for the stars!",
        author: "Ringo Starry",
        date: "2013-12-02T17:57:28.556094Z"
    },
    {
        id: 9,
        dishId: 1,
        rating: 2,
        comment: "It's your birthday, we're gonna party!",
        author: "25 Cent",
        date: "2011-12-02T17:57:28.556094Z"
    },
    {
        id: 10,
        dishId: 2,
        rating: 5,
        comment: "Imagine all the eatables, living in conFusion!",
        author: "John Lemon",
        date: "2012-10-16T17:57:28.556094Z"
    },
    {
        id: 11,
        dishId: 2,
        rating: 4,
        comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
        author: "Paul McVites",
        date: "2014-09-05T17:57:28.556094Z"
    },
    {
        id: 12,
        dishId: 2,
        rating: 3,
        comment: "Eat it, just eat it!",
        author: "Michael Jaikishan",
        date: "2015-02-13T17:57:28.556094Z"
    },
    {
        id: 13,
        dishId: 2,
        rating: 4,
        comment: "Ultimate, Reaching for the stars!",
        author: "Ringo Starry",
        date: "2013-12-02T17:57:28.556094Z"
    },
    {
        id: 14,
        dishId: 2,
        rating: 2,
        comment: "It's your birthday, we're gonna party!",
        author: "25 Cent",
        date: "2011-12-02T17:57:28.556094Z"
    },
    {
        id: 15,
        dishId: 3,
        rating: 5,
        comment: "Imagine all the eatables, living in conFusion!",
        author: "John Lemon",
        date: "2012-10-16T17:57:28.556094Z"
    },
    {
        id: 16,
        dishId: 3,
        rating: 4,
        comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
        author: "Paul McVites",
        date: "2014-09-05T17:57:28.556094Z"
    },
    {
        id: 17,
        dishId: 3,
        rating: 3,
        comment: "Eat it, just eat it!",
        author: "Michael Jaikishan",
        date: "2015-02-13T17:57:28.556094Z"
    },
    {
        id: 18,
        dishId: 3,
        rating: 4,
        comment: "Ultimate, Reaching for the stars!",
        author: "Ringo Starry",
        date: "2013-12-02T17:57:28.556094Z"
    },
    {
        id: 19,
        dishId: 3,
        rating: 2,
        comment: "It's your birthday, we're gonna party!",
        author: "25 Cent",
        date: "2011-12-02T17:57:28.556094Z"
    }
]

▶︎ comments.js

State에 데이터 담기

import { COMMENTS } from '../shared/comments';
import { LEADERS } from '../shared/leaders';
import { PROMOTIONS } from '../shared/promotions';
import {DISHES} from '../shared/dishes';

.
.
.

class Main extends Component {
  
    
    constructor(props){
        super(props);

        this.state={
            dishes: DISHES,
            commnets : COMMENTS,
            promotions : PROMOTIONS,
            leaders : LEADERS
        };
    }
    .
    .
    .

▶︎ MainComponent.js

데이터를 담은 자바스크립트 파일을 import합니다. 그리고 constructor부분에 위와같이 설정하여 state에 각 값을 넣어줍니다

 

DishdetailComponent에 넘기기

            <div>
              <Header />
              <Routes>
                  <Route path="/home" element={<HomePage/>} />
                  <Route exact path="/menu" element={<Menu dishes={this.state.dishes} />} /> // order matters
                  <Route path="/menu/:dishId" element={<DishDetail dishes={this.state.dishes} comments={this.state.commnets} />} />
                  <Route exact path="/aboutus" element={<About leaders={this.state.leaders} />}/>
                  <Route exact path="/contactus" element={<Contact/>} />
                  <Route path="*" element={<Navigate to="/home" />}/>
              </Routes>
              <Footer/>
            </div>

▶︎ MainComponent.js. 이중 Route Path="/menu/:dishId" ... 부분을 보면 됩니다

react-router-dom v6에 오면서 switch -> Routes로 바뀌었습니다. 또한 component로 쓰던 부분을 element로 변경하였습니다.

위의 :dishId라고 써있는 부분을 꼭 기억해주세요

 

dishId값 읽기 및 json array filter

useParams를 import합니다
import {Link, useParams} from 'react-router-dom'

▶︎ DishdetailComponet.js

코드 자체는 크게 별게 없습니다

        let {dishId} = useParams();
        if(props == null){
            return(
                <div></div>
            );
        }
        console.log(dishId);
        console.log(props);
        console.log(props.dishes);
        const dish = props.dishes.filter((dish) => dish.id === parseInt(dishId,10))[0];
        const comment = props.comments.filter((c) => c.dishId === parseInt(dishId,10));
        console.log(dish);

▶︎ DishdetailComponet.js 중 url parameter읽는 부분

아까 /menu/:dishId 라고 쓰신 부분이 기억날겁니다. 이 url 을 받는 위치에선 같은 이름으로 useParams()를 써야 그 값을 읽어올 수 있습니다.

즉,

let{id} = useParams(); -> 안됨

let{dishId} = useParams(); -> 됨

이렇습니다. 해보니 그렇더라고요

 아래 filter 부분은 각 array의 id값과 dishId가 동일한지 체크합니다. parseInt부분은 integer 10방식으로 바꾼다라는 뜻이랍니다.

깃허브 주소

https://github.com/Chaeguevara/courseraFulStack/tree/2a852429ca482b25c5e480630336ba5ba3597dc0/React/confusion

 

GitHub - Chaeguevara/courseraFulStack: 코세라 Front-End Web UI Frameworks and Tools: Bootstrap 4 수업 내용을 올립니

코세라 Front-End Web UI Frameworks and Tools: Bootstrap 4 수업 내용을 올립니다 - GitHub - Chaeguevara/courseraFulStack: 코세라 Front-End Web UI Frameworks and Tools: Bootstrap 4 수업 내용을 올립니다

github.com

https://stackoverflow.com/questions/64782949/how-to-pass-params-into-link-using-react-router-v6/64816926

반응형