path parameter

박은정·2021년 9월 10일
0

TIL

목록 보기
23/72
post-custom-banner

path parameter

  • path = 경로
  • react route dom 공식문서를 살펴보면 path는 경로이기 때문에 depth 형태로 나타낼 때 사용된다고 한다
  • 경로에 따라 "users/:id" path의 id의 값이 어떻게 들어왔는지 알기 위해 → this.props.match.params.id 로 접근하게 된다
  • 이때 id 라고 안하고 hello 처럼 다른 문자열로 적어도 되는데
    만약, "users/:hello"this.props.match.params.hello 로 접근하게 된다

상품상세페이지로 이동하는 방법 구상

fetch() 함수를 통해 서버에 요청한 API주소를 → 브라우저를 통해 확인할 수 있는데

  • monster path로 이동하면 → 상품리스트가 보이고
  • monster/detail/ path로 이동하면 → 해당하는 몬스터의 상세페이지로 보인다
  • monster/detail/1, monster/detail/2 이런식으로 id값까지 지정하면 → 해당하는 id값에 맞는 users 정보에 대한 상세페이지가 보인다

그래서 monster/detail/ 이라고면 경로를 입력하면 첫 번째 상품을 보여줄지, 두 번째 상품을 보여줄 지 모르는 상태이기 때문에
화면에 데이터가 제대로 구현되지 않는 것을 볼 수 있다
이러한 점을 해결하기 위해, url에 대해 id를 지정해줄 수 있다

이렇게 받은 props 안에 있는 id에 접근하기 위해서는
this.props.match.id로 하면 되는데
일단 console.log로 출력해서 어떤 데이터가 어떠한 방식으로 들어오는지 확인해야 한다

Route.js에 직결된 컴포넌트가 받는 props

json placeholder
요청주소를 주소창에 입력해서 불러올 수 있다

일단 id=1인 데이터만 잘 가져오는지 확인하기 위해서

componentDidMount() {
  fetch(`http://jsonplaceholder.typicode.com/users/1`)
  .then(res => res.json())
  .then(res => this.setState({data:res});
}

render() {
  const { data } = this.state;
  console.log(data);
  
  (..코드생략..)
  

<MonsterDetail> 컴포넌트에서 render될 때
console.log(this.props)로 props를 확인하면

이렇게 history, location, match 3개에 대한 key 및 그에 대한 객체를 받아왔다

여기 f로 되어있는거는 해당 객체에서 사용가능한 메서드라고 생각하자

서버로 요청하는 API주소 vs 브라우저에서 보이는 주소

id=1인 데이터에 대한 요청을 한건데
fetch()함수를 통해 서버로 요청하는 API주소의 id랑
브라우저에서 보이는 주소창의 id랑 다르니까 헷갈리지 않도록 주의해야 한다
따라서 브라우저 주소창의 id 값을 → fetch() 내부로 받아와야 한다

서버로 요청하는 API주소

https://jsonplaceholder/typiclode.com/users/1

브라우저에서 보이는 주소

localhost:3000/monster/detail/1

/monsters : 몬스터 목록 보여주는 페이지에서 각각의 카드를 클릭햇을 때 각각의 정보를 확인하고 싶고, 그 카드는 각각 고유의 id를 가지고 있다

각각의 카드가 id가 1,2,3,4,5인지 다 알 수 있지만
해당 카드의 경로가 들어가서는 id값을 알 수 없기 때문에
페이지를 넘어가면서도 정보가 남아야하기 때문에 해당하는 객체에 id: 1 이라는 property를 추가해준다

  1. 상품리스트에서 id=1인 상품을 클릭하면
  2. 브라우저의 주소창의 URL이 먼저 변하면서 상세페이지로 이동하고
    이때에는 아직 서버에 데이터 요청을 못한 상태이다
  3. 상세페이지의 주소창에 id가 적혀있으니까 → 그러한 id를 가지고 서버에 요청하는 URL에 넣어서 보내는 것이다

따라서 브라우저 주소창의 id를 변수처럼 서버에 보내는 URL에 활용하려면 아래처럼 적을 수 있다

componentDidMount() {
  fetch(`https://jsonplaceholder.typicode.com/users/${this.props.match,params.id}`)

Link태그를 이용해 페이지이동

상품리스트에서 해당 상품을 클릭했을 때 상세페이지로 이동해야 하기 때문에

<div className="card-list">
  {monsters.map(monster => {
    return (
      // Link태그는 react-route-dom으로부터 받는다
      <Link
        key={monster.id}
        to={`/monsters/detail/${monster.id}`}>
        <Card
          id={monster.id}
          name={monster.name}
          email={monster.email}
          />
      </Link>
      );
  • 해당 상품카드에 Link태그로 감싸주면서, 카드를 눌렀을 때 페이지가 이동되도록 입력하고
  • map()메서드에서 key값은 제일 상단의 요소에 있어야 하기 때문에 기존에 Card 태그에서 Link태그로 key속성이 이동되었다

withRouter 활용

만약 상품리스트에서 Link태그를 연결하는 것이 아니라 상품상세리스트에 해당하는 Card 컴포넌트 내부에서 withRoute를 없애고 Link태그를 연결하면 아래와 같은 에러가 발생한다

TypeError : Cannot read property 'pash' of undefined

어디서 undefined 되었나 확인하기 위해 Card 컴포넌트의 render되는 곳에 console.log(this.props)로 확인하면
Card 컴포넌트는 Route.js에 직결되어있지 않기 때문에 history, location, match에 대한 객체가 없다

이렇게 Route.js에 직결되지 않은 Card 컴포넌트에서도
history, location, match 같은 라우터기능을 사용하고 싶으면
withRouter를 Card 컴포넌트에서 사용하면 된다

withRoute 에 대해서 더 알아봐야겠다..!

상품리스트에서 상품상세 리스트로 이동하는 동적라우팅 흐름

  1. 상품리스트 페이지에서 Id를 담아 브라우저 주소창에 반영
  2. 주소창의 주소변경되어서 이러한 path는 Route.js에서 봤을 때
    이 부분에 해당하기 때문에 MonsterDetail 컴포넌트에 전달된다
<Route exact path="monster/detail/:id" component={MonterDetail}>
  1. MonsterDetail 컴포넌트에서 서버에 요청하는 API의 주소의 endpoint에 현재 주소창에서 가져온 id값을 활용한다
componentDidMount() {
  fetch(   `https://jsonplaceholder.typicode.com/users/${this.props.match.params.id}`)
  .then(res => res.json())
  .then(res => this.setState({ data: res });
}
    
profile
새로운 것을 도전하고 노력한다
post-custom-banner

0개의 댓글