코드캠프

코드캠프 5일차

Grace 2022. 9. 29. 23:24

라우팅

라우팅이랑 서버에서 클라이언트에 내가 불러오고자 하는 URL을 불러오는 것이다.

Static Routing(정적 라우터)

next/router 사용하기

import { useRouter } from 'next/router'

export default function StaticRoutingPage() {
  const router = useRouter()

  function onClickMove() {
    router.push('/05-02-static-routed')
  }

  return (
  <button onClick={onClickMove}>페이지 이동하기</button>
  )
}
const router = useRouter()

router.push('이동할 페이지')

reloae(), replace(),

  • pathname: 현재 나의 주소를 알려준다
import { useRouter } from 'next/router'

export default function StaticRoutingNumberPage() {
  const router = useRouter()

  function onClickMove1() {
    router.push('/05-04-static-routed-number/1')
  }

  function onClickMove2() {
    router.push('/05-04-static-routed-number/2')
  }

  function onClickMove3() {
    router.push('/05-04-static-routed-number/3')
  }

  return (
    <>
      <button onClick={onClickMove1}>1번 게시글</button>
      <button onClick={onClickMove2}>2번 게시글</button>
      <button onClick={onClickMove3}>3번 게시글</button>
    </>
  )
}


게시글의 수가 많아지면 폴더의 수가 많아지므로 비효율적인 방법이다.

Dynamic Routing(동적 라우터)

SPA(Singe Page Application)의 라우팅 과정

기존에는 서버로부터 해당 URL에 대한 데이터를 받아왔으나 이제는 하나의 큰 앱을 받아오는 것이며, 클라이언트(브라우저)에 해당 URL에 따라서 어떤 것을 보여줄지 결정한다.
->한 번에 앱을 받아오고 내부에서 작동하는 형식

  1. 브라우저에서 최초에 '/'루트 경로로 요청
  2. reace web app을 내려주고
  3. 내려받은 reac app 에서 루트 경로에 맞는 컴포넌트를 보여준다.
  4. react app에 다른 페이지로 이동하는 동작을 수행하면
  5. 새로운 경로에 맞는 컴포넌트를 보여준다.

    next/router

    [폴더이름]으로 변수 형태의 폴더를 생성해준다.
    http://localhost:3000/boards/`[폴더이름]`
import { useRouter } from 'next/router'

export default function DynamicRoutingNumberPage() {
  const router = useRouter()

  router.query = {

  }

  function onClickMove1() {
    router.push('/05-06-dynamic-routed-number/1')
  }
  function onClickMove2() {
    router.push('/05-06-dynamic-routed-number/2')
  }
  function onClickMove3() {
    router.push('/05-06-dynamic-routed-number/3')
  }

  return (
    <>
      <button onClick={onClickMove1}>1번 게시글</button>
      <button onClick={onClickMove2}>2번 게시글</button>
      <button onClick={onClickMove3}>3번 게시글</button>
    </>
  )
}
import { useRouter } from "next/router"

export default function DynamicRoutedNumberPage() {
  const router = useRouter()

  return (
    <div>{router.query.number}번 게시글 이동완료</div>
  )
}

react-router

react는 컴포넌트를 작성하고 렌더하며, 라우팅을 시행하기 위해서는 react-router 라이브러리를 사용해주어야한다. 가장 대표적으로 라우팅을 해주는 패키지이며 cra에 기본 내장된 패키지가 아니기 때문에 react-router를 사용하려면 설치를 진행해주어야 한다.

npm i react-router-dom

특정 경로에서 보여줄 컴포넌트를 준비한다.

import { BrowserRouter, Route } from "react-router-dom"
import Home from "./pages/Home"

export default function App() {
  return(
    <BrowserRouter>
        <Route path="/" componenet={Home} />
    </BrowserRouter>
    )
}

app.js에서 return 하단에 Route 컴포넌트에 역에 경로(path)와 컴포넌트(component)를 설정한다.
이것을 BrowserFouter로 감싸주고 브라우저에서 요청한 경로에 Route의 path가 들어잇으면 해당 컴포넌트를 보여준다.

여기서 만약

<BrowserRouter>
    <Route path="/" componenet={Home} />
      <Route path="/profile" componenet={Profile} />
</BrowserRouter>

두 가지 컴포넌트가 있을 때 profile 컴포넌트를 불러오기 위하여 /profile을 사용하면 Home과 Profile 컴포넌트 두 가지가 모두 보여지는데, 이는 Home의 path가 '/'이기 때문에 profile의 path인 '/profile'에 포함되어 있기 때문이다.

이를 정확하게 수정해주기 위해서는 exact로 해당 path와 정확히 일치하는 경우에만 해당 컴포넌트를 불러오도록 설정해주면 된다.

<BrowserRouter>
    <Route path="/" exact componenet={Home} />
      <Route path="/profile" exact componenet={Profile} />
</BrowserRouter>
<BrowserRouter>
    <Route path="/" exact componenet={Home} />
      <Route path="/profile" exact componenet={Profile} />
      <Route path="/profile/:id" componenet={Profile} />
</BrowserRouter>
export default function Profile(props) {
  const id = props.match.params.id
      return 
      <div>
      <h2>프로필페이지입니다.</h2>
      { id && <p>id는 {id} 입니다.</p>}
      </div>
}

쿼리 스트링

<BrowserRouter>
    <Route path="/" exact componenet={Home} />
      <Route path="/profile" exact componenet={Profile} />
      <Route path="/profile/:id" componenet={Profile} />
      <Route path="/about" exact componenet={About} />
</BrowserRouter>
export default function About(props) {
  const searchParams = props.location.search
  const obj = new URLSearchParams(searchParams)
  const name = obj.get("name")
      return 
      <div>
        <h2>About 페이지입니다.</h2>
          {name && <p>는 이름은 {name} 입니다.</p>}
      </div>
}

-> URLSearchParams는 바로 key로 꺼내쓰지못하며 브라우저에 따라 지원이 되지 않을 수 있다. 그러므로 query-string을 받아서 사용해주면 좋다.

query-string 사용하기

npm i query-string
import queryString from 'query-string'

export default function About(props) {
  const searchParams = props.location.search
  const query = queryString.parse(searchParms)
      return <div>About 페이지입니다.</div>
    {query.name && <p>는 이름은 {query.name} 입니다.</p>}
}

조건부 렌더링

&& 연산자

import { useQuery,gql } from "@apollo/client"
import { useRouter } from "next/router"

const FETCH_PRODUCT = gql`
  query fetchProduct($productId: ID) {
    fetchProduct(productId: $productId) {
      seller
      name
      detail
      price
    }
  }
`

export default function DynamicProductRead() {
  const router = useRouter()
  const { data } = useQuery(FETCH_PRODUCT, {
    variables: { productId: router.query.myId }
  })

  return (
    <>
      <div>판매자 {data && data.fetchProduct.seller}</div>
      <div>상품명 {data && data.fetchProduct.name}</div>
      <div>상품상세 {data && data.fetchProduct.detail}</div>
      <div>상품가격 {data && data.fetchProduct.price}</div>
    </>
  )
}

삼항연산자

data ? data.fetchProduct.seller : "loading" 
// ? 있으면
// : 없으면

optional chaining

// 있으면 보여주고 없으면 보여주지 마세용
data?.fetchProduct.seller 

try-catch 구문

  async function zzz() {
    try {
      // 일단 시도해보고
      const result = await createProduct({
        variables: {
          seller: mySeller, 
          createProductInput: {
            name: myName, 
            detail: myDetail, 
            price: Number(myPrice)
            }
        } 
      })
      console.log(result)
      router.push(`05-08-dynamic-product-read/${result.data.createProduct._id}`)
    } catch(error) {
      // 에러나면 이렇게 실행해주세요
      alert(error.message)
    }
  }

기타

주석

+) graphql 주석 시 # 사용, emotion 주석 시 /* */ 사용(HTML)과 같음. graphql은 평소처럼 ctrl+/ 사용해도 주석 오류가 발생하니 주의하도록합시다!

템플릿 리터럴

router.push(`05-08-dynamic-product-read/${result.data.createProduct._id}`)

'코드캠프' 카테고리의 다른 글

코드캠프 7일차  (1) 2022.09.30
코드캠프 6일차  (0) 2022.09.30
코드캠프 4일차  (0) 2022.09.29
코드캠프 3일차  (0) 2022.09.29
코드캠프 2일차  (0) 2022.09.29