route+ing(경로를 찾아가는 행위)
path parameter는 routes.js에서 아래처럼 정의된다.
<Router>
<Switch>
<Route exact path="/products/:id" component={ProductDetail} />
</Switch>
</Router>
:
는 path parameter가 올것임을 알리고, id
는 path parameter의 이름을 의미함.변수명 짓든 임의의 값을 넣어줄 수있다. ex) :productId
*history push 못쓰는 경우
-> withRouter HOC 사용해서
Routes.js에 이동경로 직접 안적혀있는 컴포넌트!!( 자식의 자식요소 이런것들 )
this.props.match.params.id <--- 이게 관건
id를 보내주고, 도착한 페이지에서 id를 받아옴. id를 가지고 서버에 요청을하고 받아온 데이터를 setState해서 화면에 보여준다.
Routes.js 의 Route 컴포넌트의 component 프로퍼티에 직접 연결되어 있는 하위 컴포넌트는 history, location, match 3가지 객체를 props 를 통해 제공 받습니다.
// Routes.js
<Route exact path='/product/detail/:id' component={ProductDetail} />
// ProductDetail.js
render() {
console.log(this.props) // { history: {}, location: {}, match: {}, ... }
return (
...
);
}
history
객체는 페이지 이동을 위한 여러 메서드들을 담고 있습니다. (ex, push
)location
객체는 현재 url 경로에 관한 정보를 담습니다.match
객체는 Path Parameter 에 관한 정보를 담습니다.class ProductDetail extends React.Component {
...
render() {
console.log(this.props) // { history: {}, location: {}, match: {}, ... }
return (
...
<Payment />
)
}
}
class Payment extends React.Component {
...
render() {
console.log(this.props); // {} -> history, location, match 가 없습니다.
return (
...
)
}
}
Payment 컴포넌트는 Route 에 연결되어 있지 않기 때문에, history
, location
, match
객체를 제공받지 못합니다.
하지만, Payment 컴포넌트에서도 세가지 객체를 사용하고 싶을 수 있습니다. 이 경우, 어떻게 할 수 있을까요?
withRouter HOC 가 그 기능을 제공합니다. withRouter
는 함수 입니다. 인자로 컴포넌트를 받고, 해당 컴포넌트에 3가지 객체를 추가한 컴포넌트를 반환합니다.
**import { withRouter } from 'react-router-dom';**
class Payment extends React.Component {
render() {
**console.log(this.props); // { history: {}, location:{}, match:{}, ... }**
return(
...
)
}
}
export default **withRouter(Payment);**
다시 돌아와서, 어떻게 URL 에 담겨있는 id
값을 가져올 수 있을까요?
match
객체를 이용하여 가져올 수 있습니다. Path Parameter 로 명시해둔 값은 match
객체에 담기기 때문입니다.
// ProductDetail.js
// current url -> localhost:3000/product/1
class ProductDetail extends React.Component {
...
render() {
**console.log(this.props.match.params.id) // 1**
return (
...
);
}
}
따라서 componentDidMount
메서드에서 해당 id
값을 통해 서버에 요청을 보내는 것을 통해 원하는 정보를 받아올 수 있습니다.
componentDidMount() {
**fetch(`${API}/${this.props.match.params.id}`)**
.then(res => res.json())
.then(res => ...);
지금까지의 과정을 다시 한번 그림으로 정리해보겠습니다.
동적 라우팅을 구현할 경우 일반적으로 다음과 같은 흐름으로 로직을 구현하게 됩니다.
this.props.history.push("/product/1")
로 상세 페이지로 이동합니다."http://localhost:3000/product/1"
과 같이 변경되어 있습니다.this.props.match.params.id
에서 가져올 수 있습니다.componentDidMount() {
const id = this.props.match.params.id
fetch(`http://123.456.123.123:8000/products/${id}`) // 1
.then(res => res.json())
.then(res => this.setState({ data: res }))
}
res
)를 컴포넌트의 state 객체에 저장해 줍니다.render
해줍니다.프론트 엔드에서 현재의 위치(Offset)과 추가로 보여줄 컨텐츠의 수(Limit)을 백엔드에 넘겨줘야함
현재위치. 거기로부터 몇개.
10개 씩 볼래 Limit 10
30개 씩 볼래 Limit 30
50개 씩 볼래 Limit 50
여러가지 조건들이 합쳐질때는 &표시 해주세욧
ex) product?limit=10&offset=5
product 페이지에서 5로시작해서 10개 가져와라
Query string을 가져올때는 this.props.location.search를 가져오라!
경로가 바뀌는게 아니라 그 페이지 안에서 각기 다른 옵션을 주는것
ex) 가격순, 가격범위 <<-- query string으로 한다 : 그페이지 내에서 옵션을 주는거기 때문
다른 경로로 이동을 하는게 아님.
이번에는 Pagination(Paging 이라고도 불리는) 기능에 대해 배워보겠습니다.
백엔드에서 가지고 있는 데이터는 많고, 그 데이터를 한 화면에 전부 보여줄 수 없는 경우에 사용됩니다. 모든 데이터를 한번에 보여줄 수 없다면 일정 길이로 끊어서 전달해야할 겁니다.
흔히 게시판의 "이전/다음 페이지"를 끊어 보여주는 기능으로 익숙할 텐데요. 많은 웹사이트에서 널리 사용되고 있는 개념이기에 친숙하게 느끼실 듯 합니다.
프론트엔드에서 현재의 위치(Offset)과 추가로 보여줄 컨텐츠의 수(Limit)를 백엔드에 전달합니다. 백엔드에서는 그에 해당하는 데이터를 끊어 보내주는 방식으로 구현하게 됩니다.
이 과정에서 Query Parameter(혹은, Query String, 쿼리 스트링)를 사용하게 됩니다. 쿼리 스트링이란 말 그대로 해당 엔드포인트에 대해 질의문(query)를 보내는 요청을 뜻합니다.
예를 들어, localhost:8000/product?limit=10&offset=5
라는 주소가 있다고 가정해보겠습니다. API 뒷 부분에 붙어있는 ?
로 시작하는 텍스트가 바로 쿼리스트링 입니다.
?limit=10&offset=5
의 경우, "limit이 10이면서 offset이 5일 경우의 product 페이지를 보여달라" 는 요청으로 해석됩니다.
?
기호는 쿼리스트링의 시작을 알립니다. url 에서 ?
기호는 유일무이 합니다.parameter=value
로 필요한 파라미터의 값을 적습니다.&
를 붙여서 여러개의 파라미터를 넘길 수 있습니다.쿼리스트링을 이용한 페이지 네이션 기능 또한 동적 라우팅 기능과 크게 다르지 않습니다. 두 기능의 구현 순서를 비교해보도록 하겠습니다.
리스트 페이지에서 카드를 클릭 합니다.
url 이동을 합니다. 이때, 카드의 고유한 id 값이 url 에 포함됩니다.
이동한 페이지에서, url 에 담겨있는 id 값을 match
객체를 이용하여 가져옵니다.
가져온 id 값을 이용하여 데이터를 요청합니다.
location
객체를 이용하여 가져옵니다.Path Parameter 에 대한 정보는 match
객체 안에 담겨있었듯이, 쿼리스트링에 대한 정보는 location
객체 안에 담겨있습니다.
**// current url -> localhost:3000/products?offset=10&limit=10**
class ProductList extends React.Component {
...
render() {
**console.log(this.props.location.search) // ?offset=10&limit=10**
return (
...
)
}
}
따라서 url 에서 쿼리 스트링에 대한 정보를 받아와서, 해당 정보를 통해 데이터를 요청할 수 있습니다.
fetch(`${API}${this.props.location.search}`)
.then(res => res.json())
.then(res => ...)