TIL49⎟React : 동적 라우팅

itssweetrain·2021년 4월 26일
0

React

목록 보기
8/10
post-thumbnail

동적 라우팅

라우트 경로에 특정 값을 넣어 해당하는 페이지로 이동할 수 있게 하는 것을 동적 라우팅이라 한다.

동적 라우팅 router 가 제공하는 세 가지의 객체 중 history, location 는 공백 클론 프로젝트 TIL을 통해 정리해보았다. 마지막으로 상품 리스트에서 상품 디테일로 넘어갈 때 아주 중요하게 쓰이는 match에 대해 정리해보고자 한다. 다시 간단히 정리해보자면

props 에 담아 전달해주는 세 가지의 객체는

history : 페이지 이동하거나 뒤로 가기 앞으로가기 페이지 이동에 관한 메소드 제공하는 객체
location : 현재 위치 pathname이나 search, 현재 url 경로에 대한 정보
match : pathparameter 정보


Path Parameter

라우트 경로 끝에 들어가는 id 값을 Path Parameter 라고 한다. Path Parameter 는 :id 의 형식으로 표현 된다.

<Router>  
  <Switch>
<Route exact path="/products/:productId" component={ProductDetail} />
  </Switch>
    </Router>

: 는 라우트 경로 끝에 Path Parameter 가 올것임을 알려주는 지켜줘야하는 문법
id 라는 key 값은 해당 Path Parameter 를 담을 변수명을 지정하는데, Routes.js에서 path에서 지정한 :id로 적어준 것을 가져 온것이다. (Routes.js가 기준인 것!)

상품리스트에서 상품디테일로 고유의 product id를 보내줄 때

상품 선택시, 디테일 페이지로 넘어가면서 history.push로 잘 담아 보내준다.

 goToProductDetail = id => {
    this.props.history.push(`/products/${id}`);
  };

path : '/product/detail/:id'
url : '/product/detail/2'

상품디테일에서 product id 받기

상품리스트에서 id 값을 담아 보냈다면 상품 디테일 컴포넌트에서 Path Parameter 로 주어진 id 값을 이용하여 어떻게 받아올까?

일단 보낸 값이 잘 들어왔는지 확인해보자
history.push의 path를 product detail 페이지로 설정해주었으니, 해당 컴포넌트에서 console.log(this.props)를 찍어보면

// Routes.js
<Route exact path='/products/:productId' component={ProductDetail} />

// ProductDetail.js
render() {
	console.log(this.props) // { history: {}, location: {}, match: {}, ... }
	return (
		...
	);	
}

위와 같이 Routes 의 path 속성을 작성한 후 Path Parameter 이 포함된 경로로 이동을 할 경우 component 속성에 명시한 컴포넌트가 마운트 되는 것을 확인할 수 있다.

이제 여기서 id 값은 어떻게 받아올 것인가?
match 객체를 사용해서 받아올 수 있다. this.props.match.params.productId(Routes.js에 정의한 id)만 써주면 똑똑하게 값을 찾아올 수 있다.

this.props부터 this.props.match.params까지 차례대로 찍어보면,

// ProductDetail.js
render() {
  console.log(this.props.match.params.id) // 2
	return (
		...
	);	
}

this.props.match.params의 객체 안에 id가 담겨져 있는 것을 확인할 수 있고, 우리는 이것을 이용하면 된다.

페이지에 필요한 데이터를 CDM에서 fetching하고, 해당 id와 함께 백엔드에서 만들어준 API를 호출하면 서버에서 보낸 데이터를 가지고 프론트 작업을 하면 끝!

componentDidMount() {
    const productId = this.props.match.params.productId;
    fetch(`${API}/products/${productId}`)
  //밑 생략

이렇게 하나의 변수에 넣어주고 써준다면 더욱 깔끔


withRouter

이렇듯,

Route 컴포넌트의 component 속성에 명시된 컴포넌트의 경우, history, location, match 객체가 props로 제공된다.

상품리스트 페이지에서 해당 상품클릭시 디테일로 이동하는 것을 this.props.match를 이용한 것처럼

Signup 컴포넌트에서 유저의 이름을 Welcome 컴포넌트에 넘겨줄 시, 둘다 Route 컴포넌트 속성에 명시되었었기에 this.props.history.push에 있는 pathname에 '/welcome'을 써줄 수 있었던 것이고, Welcome 컴포넌트에서도 this.props.location을 통해 값을 주고 받을 수 있었다.

하지만 Route 컴포넌트에 명시되어 있지 않은 컴포넌트에서 history 객체의 push 함수를 사용하고 싶다면?

이러한 경우 withRouter HOC를 사용할 수 있다.

import { withRouter } from 'react-router-dom';

// Comment 는 Route 에 포함되지 않은 컴포넌트
class Comment extends React.Component {
	render() {
		console.log(this.props); // { history: {}, location:{}, match:{}, ... }
		return(
			...
		)
	}
}

export default **withRouter(Comment);**

HOC(Higher Order Component) 는 함수이다.
컴포넌트를 인자로 받고, 인자로 받은 컴포넌트에 기능이 추가된 새로운 컴포넌트를 반환 한다.

즉, withRouter HOC는 history, location, match 기능이 없는 컴포넌트에 해당 기능을 추가하여 주는 것이다.

동작원리 정리

  1. 리스트 페이지에서 push 함수를 통해서 페이지 이동을 한다. 페이지 이동을 할 때 url에 id 값을 넣어서 이동을 한다
  2. url에 따라 렌더링하겠지, url이 변경되었으니 새로운 url에 매칭이 되는 새로운 컴포넌트(디테일 페이지)가 렌더링 된다
  3. 디테일 페이지에서 CDM에서 데이터를 fetch받아온다. fetch 받을 때, url에 담겨있는 id 값을 불러와서 API 끝 부분에 추가해준다
    (특정한 정보!) this.props.match.params을 이용해서 받아온다.
profile
motivation⚡️

0개의 댓글