React | Query parameters, URL parameters

양준식·2020년 3월 1일
42
post-thumbnail

Index

  • SPA, React Router
  • 리스트 페이지 >>> 상세 페이지
  • 유동 라우터
    • 유동라우터란?
    • 유동라우터 방법 두 가지
      1) Query parameters
      2) URL parameters
      - 두 가지 방법을 각각 언제 사용하는게 좋을까?
  • Wrap Up

SPA, React Router

  • SPA(Single Page Application)
  • vs. 이전의 방식
  • React Router를 통한 기능 구현
  • 참고) React 6 - React router

리스트 페이지 >>> 상세 페이지 이동

  • 많은 애플리케이션 서비스에는 리스트 페이지와 상세 페이지가 존재합니다.
  • 리스트 페이지에서 특정 아이템/상품을 클릭 시 그것에 해당하는 상세 페이지로 이동합니다.
  • "하지만 상세페이지에서 이전에 리스트 페이지에서 어떤 상품을 클릭했는지 어떻게 알고 API를 호출할까요?"
  • 지금까지 배운 방법으로 가능할까요?
  • 아래의 Routes.js 코드를 한 번 살펴봅시다.
// Routes.js
import React from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
} from 'react-router-dom';

import Home from './Pages/Home';
import List from './Pages/List';
import Detail from './Pages/Detail';

class Routes extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route exact path="/list" component={List} />
          <Route exact path="/detail" component={Detail} />
        </Switch>
      </Router>
    )
  }
}

export default Routes;
  • 위의 코드를 보면 현재 리스트 페이지와 디테일 페이지가 각각 컴포넌트로 구현되어 있고, url path로 /list, 혹은 /detail 설정 시 해당 컴포넌트로 이동하도록 되어 있습니다.
  • 하지만, 상세 페이지로 이동할 경우 화면이 나타나긴 하겠지만 어떤 상품에 대한 상세 페이지를 나타낼지 알 수 있는 방법이 없습니다.
  • 이번 시간에는 유동 라우터을 통해 리스트 페이지와 디테일 페이지를 연결하는 방법에 대해 알아보도록 하겠습니다.

동적라우팅

동적라우팅이란?

  • 동적라우팅이란? 위에서 살펴본 경우과 같이 라우트의 경로에 특정 값을 넣어 해당 페이지로 이동할 수 있게 하는 것 (Dynamic Routing)
  • React Router에서는 두 가지 방법을 통해 유동 라우팅 기능을 구현할 수 있습니다.
    1. Query parameters
    2. URL parameters
  • 각각에 대한 자세한 설명은 아래에서 예제를 통해 함께 보도록 하겠습니다.

라우트로 설정한 컴포넌트의 3가지 props

  • 라우트로 설정한 컴포넌트는 3가지의 props 를 전달받게 됩니다.
    1. history
      • 이 객체를 통해 push, replace 를 통해 다른 경로로 이동하거나 앞 뒤 페이지로 전환 할 수 있습니다.
      • 여러분들이 컴포넌트 이동(페이지 전환) 시에 this.props.history.push('/page') 를 통해 이동할 수 있었던 이유가 여기 있습니다.
    2. location
      • 이 객체는 현재 경로에 대한 정보를 지니고 있고, URL 쿼리 (/company_list?category=3)에 대한 정보도 가지고 있습니다.
    3. match
      • 이 객체에는 어떤 라우트에 매칭이 되었는지에 대한 정보가 있고 params (/company_detail/:id) 정보를 가지고있습니다.
  • 아직 이해하기 어려우시죠?🥶 위의 3가지 props가 어떻게 사용되는지 프로젝트 예제를 통해 살펴보도록 하겠습니다.
  • 전체적인 문맥의 흐름 파악이 필요한 내용이라 판단되어
    로그인 성공 >> 리스트 페이지 진입 >> 리스트 페이지 중 상품 선택 >> 해당 상품 상세 페이지로 이동
    이렇게 네 단계의 순서에 맞게 하나씩 살펴보겠습니다.

1. 로그인 성공 시 >>> 리스트 페이지

  • 로그인 성공시 리스트 페이지로 넘어가게 하는 함수입니다.
  • login을 시도하면 API와 통신하고 토큰 유무를 확인합니다.
  • 토큰이 있으면 로컬 스토리지에 저장하고,
  • /company_list?category=3 주소의 URL로 이동하도록 설정되어 있습니다.
  • company_list 페이지로 이동하는 건 알겠는데 category=3 은 무엇을 의미하는걸까요?
  • 그림은 /company_list 페이지 화면입니다.
  • 크게 3가지 카테고리가 있는데, 각각 아래와 같이 설정되어 있습니다.
  • FrontEnd : category=1 / BackEnd : category=2 / FullStack : category=3
  • 즉, 로그인 성공 시 /company_list?category=3 주소의 URL로 이동하도록 설정되어 있는 것은 처음 리스트 화면 진입 시에 FullStack에 해당하는 데이터를 화면에 보여주겠다는 뜻 입니다.
  • (참고로 현재는 API가 연결되어 있지 않아 로딩 화면만 계속 보이네요🤭)
  • 여기서 사용한 방법이 Query parameters 입니다!

🔥 Query parameters

  • url의 주소가 /company_list?category=3 인 경우
  • this.props.location을 통해서 해당 주소의 정보를 가지고 올 수 있습니다.

    location
    이 객체는 현재 경로에 대한 정보를 지니고 있고,
    URL 쿼리 (/company_list?category=3)에 대한 정보도 가지고 있습니다.

  • 아래의 코드를 보며 Query parameters에 대해 살펴보도록 하겠습니다.

2. 리스트 페이지 진입

  • 해당 코드는 리스트 페이지에서 componentDidMount 함수 안에 작성한 fetch 함수 부분입니다.
  1. 📌 this.props.location.search (코드 31번째 줄)
  • this.props.location.search에 접근합니다.
  • this.props.location.search 를 console.log로 확인 시 ?category=3 가 나옵니다. 즉, url 주소에서 /company_list 뒤에 붙은 부분이 나타납니다.
  • 그 중, backend에서 API호출 시 필요한 정보는 숫자 3 입니다.
  • 그래서 this.props.location.search.split("=")[1] 을 통해 숫자 3을 찾아 변수 queryId에 저장합니다.
  1. 📌 fetch 함수를 통한 API 호출 (코드 36번째 줄)
  • (이 부분에서는 URL parameters가 사용되었네요. 아래에서 자세히 볼거니깐 '그렇구나! 이렇게 생겼구나!' 하고 넘어가주세요.😬)
  • fetch 함수를 통한 API 호출 시, API 주소 가장 뒷 부분에 변수에 담은 숫자 3을 포함시키는 것을 확인할 수 있습니다.
  • 즉, "fullstack 데이터를 갖는 API를 호출하려면 주소 뒤에 3을 붙여줘" 라고 프론트와 백이 약속으로 정했기 때문에 프론트에서는 url 주소에서 그 숫자를 찾아 fetch 함수에서 사용하는 것입니다.
  • 그렇다면 FULLSTACK API 호출 결과 받은 해당 데이터, 즉 FullStack에 해당하는 회사 리스트를 화면에 보여줄 수 있습니다.
  • 👉 마침 backend PR 메세지가 올라왔네요! 이런식으로 상세페이지에서 어떻게 상품을 구별할지 정해지면 그에 맞게 프론트에서 필요한 데이터를 주소에 담아주면 됩니다.

🔖 cf) Query parameters 긴 경우

  • Query parameters는 & 연산자를 사용하여 얼마든지 길어질 수 있습니다.
  • 아래는 11번가 상세 페이지 url 주소입니다.
http://www.11st.co.kr/product/SellerProductDetail.tmall?method=getSellerProductDetail&prdNo=1259146705&trTypeCd=PW00&trCtgrNo=1001841
  • & 연산자를 사용하여 계속 붙어있는 Query parameters이라면 위에서 본 예시처럼 단순히 split(‘=’) 으로 필요한 value를 가져오기 어렵겠죠?
  • 이렇게 개발자가 의도한 query name의 value를 가져오기 위해선 함수를 그에 맞게 작성하여야 합니다.
  • (prdNo를 가져오는 함수를 한 번 작성해보세요!😱 조건에 맞게 함수를 작성하는게 시간이 걸리기 때문에 프로젝트 기간에는 넘어가지만, 실무에선 분명 이런 상황을 마주하게 되고 해결 방법도 알게 되실거에요!)

3. 리스트 페이지 >>> 상세 페이지 이동

  • 리스트 페이지에서 특정 상품(회사) 클릭 시 해당 상품(회사)의 상세페이지로 이동하는 부분을 살펴보겠습니다.
  • 리스트 페이지 안에 CompanyItem 컴포넌트가 map 함수를 통해 렌더되고 있습니다.
  • 그 중 props 값으로 jobId가 부여되는 것을 볼 수 있습니다. 이 데이터가 상세페이지로 넘어가는데 필요한 데이터 입니다.
  • CompanyItem 컴포넌트의 내부를 살펴보도록 하겠습니다.
  • CompanyItem 클릭 시 해당 상품(회사)의 디테일 페이지로 이동할 수 있게끔 전체가 Link태그로 감싸져 있습니다.
  • 이동 경로는 to={`/company_detail/${this.props.jobID}`} 로 설정되어 있습니다.
  • company_detail 페이지로 이동하는데 해당 상품(회사)의 jobID를 뒤에 덧붙여서 어떤 상품에 대한 상세페이지로 이동할 것인지 정해주는 겁니다.
  • 여기서 사용되는 방법이 URL parameters 입니다!

🔥 URL parameters

match
이 객체에는 어떤 라우트에 매칭이 되었는지에 대한 정보가 있고 params (/company_detail/:id) 정보를 가지고있습니다.

  • params 정보는 this.props.match.params 를 통해 가지고 올 수 있습니다.
  • 이렇게 params 데이터를 사용하기 위해서는 Routes.js에서 CompanyDetail의 라우트 설정을 조금 수정해 주어야 합니다.

🚨 주의) URL 쿼리의 경우엔 컴포넌트 내에서 동적으로 사용 할 수 있고, params 의 경우엔 사용하기 전에 꼭 라우트에서 지정을 해주어야합니다.

  • Routes.js
  • 이렇게 <Route path="/company_detail/:id" component={CompanyDetailPage} /> 지정할 경우, CompanyDetailPage 컴포넌트에서 this.props.match.params.id를 통해 해당 값을 가지고 올 수 있습니다.
  • 상세 페이지 코드를 통해 확실히 이해해 보도록 하겠습니다.

4. 상세 페이지 진입

  • CompanyDetailPage.js
  • fetch 함수 부분에 API 호출 시 API 주소 뒤에 this.props.match.params.id가 덧붙어 있습니다.
  • 리스트 페이지에서 특정 상품(회사) 클릭 시 Link 태그 안에 이동 경로가 어떻게 되었는지 기억하시나요? 아래 코드를 확인하면서 정리해보도록 하겠습니다
// Routes.js - CompanyDetailPage 라우트 설정
<Route exact path="/company_detail/:id" commponent={CompanyDetailPage} />

// CompanyItem.js - List 페이지에서 상품 클릭 시 상세 페이지 이동 경로 설정
<Link to={`/company_detail/${this.props.jobId}`}> ... </Link>

// 상세 페이지 진입 시 API 호출 주소 
fetch(`http://10.58.7.182:8001/job/recruitment/${this.props.match.params.id}`)
  • List 페이지에서 상품 클릭 시 해당 상품의 jobId를 포함한 url 주소로 이동합니다.
  • CompanyDetailPage에서는 url 주소에 담긴 jobID를 this.props.match.params.id를 통해 접근할 수 있습니다.
  • 접근해서 얻은 jobID를 통해 API를 호출하여 해당 데이터를 얻고 화면에 나타냅니다.

🧐 두 가지 방법을 각각 언제 사용하는게 좋을까?

String parameters

  • 해당 페이지에서 여러 정보가 필요한 경우
  • Query parameters를 사용하고 싶은 경우 routes.js를 수정해야 하기 때문에 유지 보수 측면에서 좋지 않다고 판단 될 경우
  • 필터링을 하고 싶은 경우

Query parameters

  • 특정한 resource를 식별하고 싶은 경우. 즉, 하나만 딱 필요한 경우
/users // 사용자 전체의 목록을 가져온다.
/users/123 // id 값이 123인 사용자를 가져온다.
/users?job=programer // 필터링 >>> 직업이 프로그래머인 사용자 목록만 가져온다.

Wrap-up

  • SPA(Single Page Application)을 구축하기 위해선 라우팅 기능이 반드시 필요하면, React Router 라이브러리를 사용하여 해당 기능을 구현할 수 있습니다.
  • 유동라우터란 라우트의 경로에 특정 값을 넣어 해당 페이지로 이동할 수 있게 하는 것인데, React Router에서는 두 가지 방법을 통해 유동 라우팅 기능을 구현할 수 있습니다.
  • 1) Query String, 2) URL Parameters
  • ❗️위의 기능은 백앤드의 API와는 상관이 없습니다❗️
    오로지 프론트의 서로 다른 페이지(ex. 메인페이지 & 상세페이지) 이동시 서로 소통하기 위함이지, API 호출 시에는 url 주소에서 필요한 데이터만 골라내 A호출 시 사용하는 것일 뿐입니다.
profile
실력, 심력, 체력, 영력의 균형있는 성장을 추구합니다.

0개의 댓글