프론트엔드 공부/React

37일차 프론트엔드 공부 - Routing

프망생222 2024. 11. 17. 17:00

- 프론트엔드 공부 37일차 -

 

Router

페이지 이동과 관련된 기능을 가지고 있는 객체

 

routing이란?

페이지 이동

 

const router = useRouter()

router.push(“이동할 페이지”)

 

ex)

 

이동하기 전 페이 JS

import {useRouter} from 'next/router'

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

    const onClickMove =() => {
        router.push("/day05/05-01-static-routing-moved")
    }

    return(
        <button onClick={onClickMove}>페이지 이동</button>
    )
}

이동할 페이지 JS

export default function StaticRoutingMovedPage(){

    return(
        <div>페이지 이동이 완료되었습니다.</div>
    )    
}

 

페이지 이동 전
페이지 이동 버튼 터치 후

 

 

페이지 이동 버튼이 여러개 있는 페이지 ex)

 

import {useRouter} from 'next/router'

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

    const onClickMove1 =() => {
        router.push("/day05/05-02-static-routing-board-moved/1")
    }

    const onClickMove2 =() => {
        router.push("/day05/05-02-static-routing-board-moved/2")
    }

    const onClickMove3 =() => {
        router.push("/day05/05-02-static-routing-board-moved/3")
    }

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

 

export default function StaticRoutingMovedPage(){

    return(
        <div>1번 게시글 이동이 완료되었습니다.</div>
    )    
}

1, 2, 3번 게시글 JS의 기본 형태는 비슷함

 

 

 

1번 게시글 이동

 

2번 게시글 이동

 

3번 게시글 이동

 

/day05/05-02-static-routing-board-moved 폴더에 이동하 게시글인 1, 2, 3 폴더를 새로 만들어줘야 한다.

 

 

DB에서 데이터 가져오기

const { data } = useQuert(FETCH_BOARD)

 

const FETCH_BOARD = gql`
  query {
    fetchBoard(number: 1) {
      number
      writer
      title
      contents
    }
  }
`

 

각각의 데이터를  사용하는 법

data.fetchBoard.writer

data.fetchBoard.title

data.fetchBoard.contents

 

JavaScript는 데이터를 요청하고 응답을 받아올 동안 데이터의 값이 undefined이기 때문에 에러가 발생한다.

이를 해결하깅 위해 조건부 렌더링을 사용한다.

 

조건부 렌더링

삼항 연산자

data ? data.fetchProfile : "가나다"

data.fetchProfile가 존재하지 않으면 "가나다"로 데이터를 반환해준다.

 

&& 연산자

data && data.fetchProfile

data가 존재하지 않을 경우 자동으로 undefined를 반환해준다.

 

옵셔널 체이닝 (Optional-Chaining)

data?.fetchProfile

&&연산자를 더 간결하게 사용하기위한 방법

 

 

data || data.fetchProfile

data 값이 거짓이면 data.fetchProfile 실

 

Nullish Coalescing

data ?? data.fetchProfile

data 값이 비어있으면 data.fetchProfile 실행

 

import { useQuery, gql } from "@apollo/client";

const FETCH_BOARD = gql`
  query {
    fetchBoard(number: 11721) {
      number
      writer
      title
      contents
    }
  }
`

export default function StaticRoutingMovedPage() {
  const { data } = useQuery(FETCH_BOARD);
  console.log(data);

  return (
    <div>
      <div>1번 게시글 이동이 완료되었습니다.</div>
      <div>작성자: {data && data.fetchBoard.writer}</div>
      <div>제목: {data?.fetchBoard.title}</div>
      <div>내용: {data ? data.fetchBoard.contents : "로딩중"}</div>
    </div>
  );
}

 

 

 

동적 라우팅

게시글이 1000개가 넘어가면 폴더를 1000개 이상 만들어야한는 번거러움이 존재하게 된다.

이를 효과적으로 하기위해 사용하는 방법으로는 동적라우팅이 있다.

폴더 예시

보여주고자 하는 폴더 이름을 [boardId]로 작성하여서 사용할 수 있다.

대괄호로 감싸준 폴더를 만들어주게 되면 이동하고자 하는 게시글 번호가 대괄호 안에 쓰여진 변수명에 담게되어 그 변수 안의 데이터를 사용할 수 있게 된다.

 

동적 라우팅 사용

import {useRouter} from 'next/router'

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

    const onClickMove1 =() => {
        router.push("/day05/05-04-dynamic-routing-board-query-moved/11721")
    }

    const onClickMove2 =() => {
        router.push("/day05/05-04-dynamic-routing-board-query-moved/11722")
    }

    const onClickMove3 =() => {
        router.push("/day05/05-04-dynamic-routing-board-query-moved/11723")
    }

    return(
        <div>
            <button onClick={onClickMove1}>11721번 게시글로 이동</button>
            <button onClick={onClickMove2}>11722번 게시글로 이동</button>
            <button onClick={onClickMove3}>11723번 게시글로 이동</button>
        </div>
    )
}

 

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

const FETCH_BOARD = gql`
  query fetchBoard($number: Int){
    fetchBoard(number: $number) {
      number
      writer
      title
      contents
    }
  }
`

export default function DynamicRoutingMovedPage() {
  const router = useRouter()
  const { data } = useQuery(FETCH_BOARD, {
    variables: {
      number: Number(router.query.num)
    }
  });
  console.log(data);

  return (
    <div>
      <div>{router.query.num}번 게시글 이동이 완료되었습니다.</div>
      <div>작성자: {data?.fetchBoard?.writer}</div>
      <div>제목: {data?.fetchBoard?.title}</div>
      <div>내용: {data?.fetchBoard?.contents}</div>
    </div>
  );
}

 

 

11721 게시글 이동
11722 게시글 이동

 

동적 라우팅을 이용하여 URL에 숫자만 변경해도 해당 번호의 DB 데이터를 가져올 수 있도록 수정하였다.

      <div>작성자: {data?.fetchBoard?.writer}</div>
      <div>제목: {data?.fetchBoard?.title}</div>
      <div>내용: {data?.fetchBoard?.contents}</div>

 

fetchBoard? 라고 작성한 이유?

fetchBoard에 데이터가 없을 경우도 있기 때문

 

 

try

try에 있는 내용을 시도하다가 실패하면 다음에 있는 모든 줄을 무시하고 catch에 있는 내용이 실행

 

try {

   new()

   b()

} catch(error){

    alert(error.message)

}

 

new() 실행에 실패하면 b() 함수를 실해하지 않고 alert(error.message)를 실행하게 된다.

 

 

게시글 생성 후 생성한 페이지로 바로 이동하기

 

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

const MyGarphqlSetting = gql`
  mutation createBoard($writer: String, $title: String, $contents: String) {
    createBoard(writer: $writer, title: $title, contents: $contents) {
      _id
      number
      message
    }
  }
`;

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

  const [나의함수] = useMutation(MyGarphqlSetting);

  const onClickSubmit = async () => {

    try{

      const result = await 나의함수({
        variables: {
          writer: "짱구",
          title: "안녕하세요",
          contents: "반갑습니다.",
        },
      });
      console.log(result);
      // router.push("/day05/05-05-dynamic-routing-board-mutation-moved/" + result.data.createBoard.number)
      router.push(`/day05/05-05-dynamic-routing-board-mutation-moved/${result.data.createBoard.number}`)
    
    }catch(error){
      alert(error.message)
    }

    
  };

  return <button onClick={onClickSubmit}>Graphql-API 요청하기</button>
}

 

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

const FETCH_BOARD = gql`
  query fetchBoard($number: Int){
    fetchBoard(number: $number) {
      number
      writer
      title
      contents
    }
  }
`

export default function DynamicRoutingMovedPage() {
  const router = useRouter()
  const { data } = useQuery(FETCH_BOARD, {
    variables: {
      number: Number(router.query.num)
    }
  });
  console.log(data);

  return (
    <div>
      <div>{router.query.num}번 게시글 이동이 완료되었습니다.</div>
      <div>작성자: {data?.fetchBoard?.writer}</div>
      <div>제목: {data?.fetchBoard?.title}</div>
      <div>내용: {data?.fetchBoard?.contents}</div>
    </div>
  );
}

 

게시글 생성 전
게시글 생성 후