๐Ÿ’ช React. Dynamic Routing

[meษช]ยท2021๋…„ 9์›” 9์ผ
0

1-3. Today I Learned. React.js

๋ชฉ๋ก ๋ณด๊ธฐ
6/9

๐Ÿ“Œ ๊ฐœ๋ฐœ ๊ณต๋ถ€ 1๊ฐœ์›” ์ฐจ์ธ to-be ๊ฐœ๋ฐœ์ž์˜ ์ž์Šต ๋ธ”๋กœ๊ทธ๐Ÿ™‚๏พ Aug 30 ~ Sep 3, 2021

ํ˜„์žฌ ์ƒํƒœ

https://www.notion.so/wecode/React-2-React-Router-Sass-fdcb50b662814a2c95f600fced8ab42c

๊ณต์‹ ๋ฌธ์„œ

Dynamic Routing

๋ผ์šฐํŠธ ๊ฒฝ๋กœ์— ํŠน์ • ๊ฐ’์„ ๋„ฃ์–ด ํ•ด๋‹นํ•˜๋Š” ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

> Path Parameter

localhost:3000/product/2
localhost:3000/product/45
localhost:3000/product/125

pagination ๋˜์–ด ์žˆ์ง€ ์•Š์•„๋„ ์œ„์ฒ˜๋Ÿผ ๊ฒฝ๋กœ parameter๊ฐ€ ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ํ™”๋ฉด์œผ๋กœ ์ด๋™ ๊ฐ€๋Šฅ
2, 45, 125๊ฐ€ ๊ฐ๊ธฐ ๋‹ค๋ฅด id ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๋งค๊ฐœ ๋ณ€์ˆ˜

> Routes component์—์„œ์˜ path parameter ์ •์˜

<Router>
	<Switch>
		<Route exact path='/product/:id' component={productDetail} />
	</Switch>
</Router>
  • : ๋Š” path parameter ๊ฐ€ ์˜ฌ ๊ฒƒ์ž„์„ ์˜๋ฏธ
  • id ๋Š” ํ•ด๋‹น path parameter ์˜ ์ด๋ฆ„์„ ์˜๋ฏธ (๋ณ€์ˆ˜ ๋ช…์„ ์ง“๋“ฏ์ด ์ž„์˜์˜ ์ด๋ฆ„ ์ง€์ • ๊ฐ€๋Šฅ ex :productId)

> ex

  1. ์ œํ’ˆ ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด onClick event ์‹œ ๋ฐœ์ƒํ•˜๋Š” push ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด /product/1๋กœ ์ด๋™
  • URL์ด /product/1๋กœ ๋ณ€ํ•˜๋ฉด Route component์— ์ •์˜๋˜์–ด ์žˆ๋Š” path='/product/:id์— ๋”ฐ๋ผ ProductDetail component๊ฐ€ mount๋จ
  1. ProductDetail component์—์„œ๋Š” BE์— id๊ฐ€ 1์ธ item์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์š”์ฒญ
  2. ์‘๋‹ต์œผ๋กœ ๋ฐ›์€ setState ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด state์— ์ €์žฅํ•˜๊ณ , ์ด๋ฅผ ํ†ตํ•ด ์ƒ์„ธ page UI render๋จ

history, match, location object

์œ„ ์„ธ ๊ฐ€์ง€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด URL์˜ id ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
Routes.js ์˜ Route component์˜ component property์— ์ง์ ‘ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ํ•˜์œ„ component๋Š” history, location, match 3๊ฐ€์ง€ ๊ฐ์ฒด๋ฅผ props๋ฅผ ํ†ตํ•ด ์ œ๊ณต ๋ฐ›๋Š”๋‹ค.
์•„๋ž˜ ProductDetail component๋Š” Route component๋ฅผ ํ†ตํ•ด 3๊ฐ€์ง€ ๊ฐ์ฒด๋ฅผ ์ œ๊ณต ๋ฐ›๋Š”๋‹ค.

// Routes.js
<Route exact path='/product/detail/:id' component={ProductDetail} />
// ProductDetail.js
render() {
	console.log(this.props) // { history: {}, location: {}, match: {}, ... }
	return (
		...
	);	
}
  • history ๊ฐ์ฒด๋Š” ํŽ˜์ด์ง€ ์ด๋™์„ ์œ„ํ•œ ์—ฌ๋Ÿฌ method๋“ค์„ ๋‹ด๊ณ  ์žˆ์Œ ex push
  • location ๊ฐ์ฒด๋Š” ํ˜„์žฌ url ๊ฒฝ๋กœ์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด์Œ
  • match ๊ฐ์ฒด๋Š” path parameter ์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด์Œ

ํŽ˜์ด์ง€ ์ด๋™์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋˜ push ํ•จ์ˆ˜๋„ history ๊ฐ์ฒด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ
ex onClick={ () โ‡’ this.props.history.push('/main') }

โœ“

Q ๊ทธ๋Ÿผ ๊ทธ๋ƒฅ link ๊ฑธ๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€?
A link๋Š” ์ƒˆ๋กœ๊ณ ์นจ๋˜๊ณ , ๋™์  routing์€ log๊ฐ€ ๋ˆ„์ ๋จ

> (+) withRouter HOC

history, location, match๋Š” Route component๊ฐ€ component property์— ์—ฐ๊ฒฐ ๋˜์–ด ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์— ์ œ๊ณตํ•˜๋Š” ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— component๊ฐ€ Route์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด withRouter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

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

class Payment extends React.Component {
	render() {
		console.log(this.props); // { history: {}, location:{}, match:{}, ... }
        // Payment component๋Š” Router์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€ ์•Š์•„์„œ history, location, match ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— withRouter๋ฅผ ์ ์Œ
		return(
			...
		)
	}
}

export default withRouter(Payment);

this.props.match.params.id

path parameter๋กœ ๋ช…์‹œํ•ด๋‘” ๊ฐ’์€ match ๊ฐ์ฒด์— ๋‹ด๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— match ํ•จ์ˆ˜๋กœ URL์— ๋‹ด๊ฒจ์žˆ๋Š” id ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
๊ทธ๋ž˜์„œ componentDidMount method์— ํ•ด๋‹น id๋ฅผ ์ž…๋ ฅํ•ด server์— ์š”์ฒญํ•˜์—ฌ ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ

// ProductDetail.js
// current URL -> localhost:3000/product/1

class ProductDetail extends React.Component {
	...
	render() {
		console.log(this.props.match.params.id) // 1
		return (
			...
		);	
	}
}
componentDidMount() {
	fetch(`${API}/${this.props.match.params.id}`)
	.then(res => res.json())
	.then(res => ...);

summary

  • ๊ฐœ๋ณ„ ์ƒํ’ˆ ํด๋ฆญ
    โ†’ this.props.history.push("/product/1") ๋กœ ์ƒ์„ธ page๋กœ ์ด๋™
  • ์ƒ์„ธ page๋กœ ์ด๋™ ์‹œ URL์ด "http://localhost:3000/product/1" ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝ
  • page์— ํ•„์š”ํ•œ daat๋ฅผ componentDidMount ์—์„œ fetching
    • ํ•„์š”ํ•œ id๋Š” URL์— ์กด์žฌํ•˜๋ฏ€๋กœ this.props.match.params.id์—์„œ ๊ฐ€์ ธ์˜ด
    • ํ•ด๋‹น id๋ฅผ ๊ฐ€์ง€๊ณ  BE์—์„œ ๋งŒ๋“ค์–ด์ค€ API๋ฅผ ํ˜ธ์ถœ
      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 }))
      }
  • server์—์„œ ๊ฐ€์ ธ์˜จ data (res)๋ฅผ ์ปดํฌ๋„ŒํŠธ์˜ state ๊ฐ์ฒด์— ์ €์žฅ
  • state ๊ฐ์ฒด์— ๋‹ด๊ธด data๋กœ component UI ๋ฅผ render
profile
๋Š๋ ค๋„ ํ•  ๊ฑฐ์•ผ.......

0๊ฐœ์˜ ๋Œ“๊ธ€