๐Ÿท๏ธ [๋ชฉ์ฐจ]

  • ๋ผ์šฐํ„ฐ ๊ฐ์ฒด์™€ ๋ผ์šฐํŒ…
  • ์ •์ ๋ผ์šฐํŒ…๊ณผ ๋™์ ๋ผ์šฐํŒ…
  • ๋น„๋™๊ธฐ ํ†ต์‹ ๊ณผ ์กฐ๊ฑด๋ถ€๋ Œ๋”๋ง
  • graphql ๋ฎคํ…Œ์ด์…˜์— try ~ catch ์ ์šฉ
  • Apollo ๋””๋ฒ„๊น… ํˆด(Apollo-Client-Devtools)

๐Ÿ–‡๏ธ [์ถœ์ฒ˜ ๋ฐ ์ฐธ์กฐ]

์ฝ”๋“œ์บ ํ”„
MDN
https://medium.com/w-bs-log/history-push%EC%99%80-replace%EC%9D%98-%EC%B0%A8%EC%9D%B4-ed5f2f7db7dc
https://www.zerocho.com/category/HTML&DOM/post/599d2fb635814200189fe1a7
https://e-juhee.tistory.com/entry/router-push-router-replace


๐Ÿ’ก ๋ผ์šฐํ„ฐ ๊ฐ์ฒด์™€ ๋ผ์šฐํŒ…

โœ… ๋ผ์šฐํ„ฐ(router) ๊ฐ์ฒด๋ž€โ“

ํŽ˜์ด์ง€ ์ด๋™๊ณผ ๊ด€๋ จ๋œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋กœ, ๋ผ์šฐํŒ…์ด๋ž€ ํŽ˜์ด์ง€์ด๋™์ด๋‹ค.
์ด ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด A ํŽ˜์ด์ง€์—์„œ B ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ๋•Œ, "B ํŽ˜์ด์ง€๋กœ ๋ผ์šฐํŒ…ํ•œ๋‹ค" ๊ณ  ๋งํ•œ๋‹ค.

ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•˜๊ธฐ ์œ„ํ•ด useRouter() ๋ผ๋Š” ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

const router = useRouter()
const rounter.push("์ด๋™ํŽ˜์ด์ง€")

๐Ÿ’ก ์ •์ ๋ผ์šฐํŒ…๊ณผ ๋™์ ๋ผ์šฐํŒ…

โœ… ์ •์ ๋ผ์šฐํŒ…

login ํŽ˜์ด์ง€๋Š” ๋ˆ„๊ฐ€ ์–ธ์ œ ์ ‘์†ํ•ด๋„ ํ•ญ์ƒ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์„ "์ •์  ๋ผ์šฐํŒ…ํ•œ๋‹ค"๊ณ  ํ•œ๋‹ค.

โ–ผ ์‹ค์Šต

  • ํŽ˜์ด์ง€ ์กฐํšŒํ•˜๊ธฐ
//05-01-static-routing
import { useRouter } from "next/router";
export default function StaticRoutingPage() {
const router = useRouter();
const onClickMove = () => {
    router.push("/section05/05-01-static-routing-moved");
  };
return <button onClick={onClickMove}>ํŽ˜์ด์ง€ ์ด๋™</button>;
}
;
// 05-01-static-routing-moved
export default function StaticRoutingPage() {
  return <div>์ด๋™์™„๋ฃŒ</div>;
}
  • ํŽ˜์ด์ง€ ์ด๋™ํ•˜๊ธฐ
//05-02-static-routing-board
import { useRouter } from "next/router";
export default function StaticRoutingPage() {
const router = useRouter();
const onClickMove1 = () => {
    router.push("/section05/05-02-static-routing-board-moved/1");
  };
  const onClickMove2 = () => {
    router.push("/section05/05-02-static-routing-board-moved/2");
  };
  const onClickMove3 = () => {
    router.push("/section05/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>
  );
};
//05-02-static-routing-board-moved/1
export default function StaticRoutingPage() {
  return <div>1๋ฒˆ ์ด๋™์™„๋ฃŒ</div>;
}
//05-02-static-routing-board-moved/2
export default function StaticRoutingPage() {
  return <div>2๋ฒˆ ์ด๋™์™„๋ฃŒ</div>;
}
//05-02-static-routing-board-moved/3
export default function StaticRoutingPage() {
  return <div>3๋ฒˆ ์ด๋™์™„๋ฃŒ</div>;
}
  • ํŽ˜์ด์ง€ ์ „ํ™˜ํ•˜๊ธฐ
//05-03-static-routing-board-query
import { useRouter } from "next/router"; 
export default function StaticRoutingPage() {
  const router = useRouter();
  const onClickMove1 = () => {
    router.push("/section05/05-03-static-routing-board-query-moved/1");
  };
  const onClickMove2 = () => {
    router.push("/section05/05-03-static-routing-board-query-moved/2");
  };
  const onClickMove3 = () => {
    router.push("/section05/05-03-static-routing-board-query-moved/3");
  };
return (
    <div>
      <button onClick={onClickMove1}>1๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ์ด๋™</button>;
      <button onClick={onClickMove2}>2๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ์ด๋™</button>;
      <button onClick={onClickMove3}>3๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ์ด๋™</button>;
    </div>
  );
}
//05-03-static-routing-board-query-moved/2
import { useQuery, gql } from "@apollo/client";
const FETCH_BOARD = gql`
  query {
    fetchBoard(number: 2) {
      number
      writer
      title
      contents
    }
  }
`;
export default function StaticRoutingPage() {
  const { data } = useQuery(FETCH_BOARD);
  return (
    <div>
      <div>2๋ฒˆ ์ด๋™์™„๋ฃŒ</div>
      <div>์ž‘์„ฑ์ž : {data.fetchBoard.writer}</div>
      <div>์ œ๋ชฉ : {data.fetchBoard.title}</div>
      <div>๋‚ด์šฉ : {data.fetchBoard.contents}</div>
    </div>
  );
}

โœ… ๋™์ ๋ผ์šฐํŒ…

๊ฒŒ์‹œํŒ ์ƒ์„ธ๋ณด๊ธฐ์™€ ๊ฐ™์€ ๊ฒฝ์šฐ ๊ธ€ ๋ฒˆํ˜ธ์— ๋”ฐ๋ผ ์ฃผ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค.
๋งŒ์•ฝ ๊ฒŒ์‹œ๊ธ€์ด 1000๊ฐœ๊ฐ€ ๋„˜์–ด๊ฐ€๊ฒŒ ๋˜๋ฉด ๊ฐ๊ฐ์˜ ๊ธ€ ๋ฒˆํ˜ธ์— ๋”ฐ๋ผ ํŽ˜์ด์ง€๋ฅผ 1000๊ฐœ์”ฉ ๋งŒ๋“ค์–ด ์ •์ ๋ผ์šฐํŒ…์„ ํ•ด์ฃผ๊ธฐ๋Š” ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์—,
ํšจ๊ณผ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋™์  ๋ผ์šฐํŒ…์„ ์‚ฌ์šฉํ•œ๋‹ค.

/board/1 โ‡’ 1๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ๋ณด๊ธฐ ํŽ˜์ด์ง€
/board/2 โ‡’ 2๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ๋ณด๊ธฐ ํŽ˜์ด์ง€
/board/3 โ‡’ 3๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ๋ณด๊ธฐ ํŽ˜์ด์ง€
/board/4 โ‡’ 4๋ฒˆ ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ๋ณด๊ธฐ ํŽ˜์ด์ง€

next.js์—์„œ๋Š” ๋™์  ๋ผ์šฐํŒ…์„ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

์œ„ ํด๋” ๊ตฌ์กฐ์™€ ๊ฐ™์ด ๋ณด์—ฌ์ฃผ๊ณ ์ž ํ•˜๋Š” ํด๋” ์ด๋ฆ„์˜ ํ•˜์œ„ ํด๋”๋กœ
[boardId]ํด๋”๋ฅผ ๋งŒ๋“ค์–ด ์ค€ ํ›„
์ด ์•ˆ์— index.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ฃผ๋ฉด ๋™์  ๋ผ์šฐํŒ…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
๋Œ€๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ์ค€ ํด๋”๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋ฉด ์ด๋™ํ•ด์ฃผ๊ณ ์ž ํ•˜๋Š” ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ,
ํ˜น์€ ๊ฒŒ์‹œ๊ธ€ ๋ฒˆํ˜ธ๊ฐ€ ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ์“ฐ์—ฌ์ง„ ๋ณ€์ˆ˜๋ช…์— ๋‹ด๊ฒจ์ ธ ๊ทธ ๋ณ€์ˆ˜ ์•ˆ์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
(์ด ๋•Œ, ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ์“ฐ์—ฌ์ง€๋Š” ํด๋” ์ด๋ฆ„์€ ๋‹จ์ˆœํžˆ ๋ณ€์ˆ˜๋ช…์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•ด๋„ ์ƒ๊ด€์—†๋‹ค.)
์ด๋Ÿฌํ•œ ๊ณผ์ •์„ router ๊ฐ์ฒด๊ฐ€ ๋„์™€์ฃผ๋Š” ๊ฒƒ!

์‹ค์ œ๋กœ router.query = { boardId: 1 } ์ด๋Ÿฐ ํ˜•์‹์œผ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋ฉด์„œ ์ž๋™์œผ๋กœ ๊ฒŒ์‹œ๊ธ€ ๋ฒˆํ˜ธ๋ฅผ ๊บผ๋‚ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.


โ–ผ ์‹ค์Šต

[qqq]
import { useQuery, gql } from "@apollo/client";
import { useRouter } from "next/router";
//playground์—์„œ ์—ฐ์Šตํ•˜๊ณ  ๋ณต๋ถ™
const FETCH_BOARD = gql`
  query fetchBoard($number: Int) {
    fetchBoard(number: $number) {
      number
      writer
      title
      contents
    }
  }
`;
export default function StaticRoutingPage() {
  const router = useRouter();
  console.log(router);
  const { data } = useQuery(FETCH_BOARD, {
    variables: {
      number: Number(router.query.qqq), //"๋ฌธ์ž์—ด" -> ์ˆซ์ž
    },
  });
  console.log(data); //์ž˜ ๋ฌ๋Š”์ง€ ์กฐํšŒํ•˜๊ธฐ
  return (
    <div>
      <div>2๋ฒˆ ์ด๋™์™„๋ฃŒ</div>
      <div>์ž‘์„ฑ์ž : {data && data?.fetchBoard?.writer}</div>
      <div>์ œ๋ชฉ : {data?.fetchBoard?.title}</div>
      <div>๋‚ด์šฉ : {data ? data?.fetchBoard?.contents : "๋กœ๋”ฉ์ค‘์ž…๋‹ˆ๋‹ค"}</div>
    </div>
  );
}

โœ… ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์šฐํ„ฐ(router) ๊ฐ์ฒด ๊ธฐ๋Šฅ

import Router from 'next/router'
export default function Routing() {
    const handleClickPathname = () => {
        const pathname = Router.pathname
        alert(pathname)
    }
	const handleClickAsPath = () => {
        const asPath = Router.asPath
        alert(asPath)
    }
    const handleClickBack = () => {
        Router.back()
    }
    const handleClickPush = () => {
        Router.push('/')
    }
    const handleClickReload = () => {
        Router.reload()
    }
    const handleClickReplace = () => {
        Router.replace('/')
    }
    return (
      <>
        <button onClick={handleClickPathname}>ํ˜„์žฌ ์œ„์น˜ ์ฃผ์†Œ: Router.pathname</button><br/>
        <button onClick={handleClickAsPath}>ํ˜„์žฌ ์œ„์น˜ ์ฃผ์†Œ: Router.asPath</button><br/>
        <button onClick={handleClickBack}>๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ: Router.back()</button><br/>
        <button onClick={handleClickPush}>ํ˜„์žฌ ํŽ˜์ด์ง€์—์„œ, ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™: Router.push()</button><br/>
        <button onClick={handleClickReload}>์ƒˆ๋กœ๊ณ ์นจ: Router.reload()</button><br/>
        <button onClick={handleClickReplace}>ํ˜„์žฌ ํŽ˜์ด์ง€ ์‚ญ์ œ ํ›„, ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์ด๋™: Router.replace()</button><br/>
      </>
    )
  }

-> ๋Œ€๊ด„ํ˜ธ๊ฐ€ ์žˆ๋Š” ํด๋”๋ฅผ ๋‹ค์ด๋‚˜๋ฏน ๋ผ์šฐํŒ… ํด๋”, ๋Œ€๊ด„ํ˜ธ๊ฐ€ ์—†๋Š” ํด๋”๋Š” ์ •์ ๋ผ์šฐํŒ…

โ—๏ธ์ถ”๊ฐ€ํ•™์Šต์ฃผ์ œ

1. ๋ผ์šฐํ„ฐ ๊ฐ์ฒด์˜ push์™€ replace ์˜ ์ฐจ์ด์™€ ์‚ฌ์šฉ ์˜ˆ์‹œ

๋ผ์šฐํŒ… ๋ณ€๊ฒฝ ์‹œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฉ”์†Œ๋“œ ์ค‘ push์™€ replace๊ฐ€ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด HOME > Page1 > Page2 > Page3 ์ˆœ์œผ๋กœ ํŽ˜์ด์ง€ ์ด๋™์„ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

Page2์—์„œ history.push()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด

import React from 'react';
function Page2({ history }) {
history.push('/Page3');
return <div>Page2</div>;
}
export default Page2;

HOME > Page1 > Page2 > Page3 ์ˆœ์„œ๋Œ€๋กœ history์— ์Œ“์—ฌ, ๋งˆ์ง€๋ง‰ Page3 ์—์„œ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ฒŒ ๋˜๋ฉด Page2๋กœ ๋Œ์•„๊ฐ€๊ฒŒ ๋œ๋‹ค.

๋˜‘๊ฐ™์€ ์ƒํ™ฉ์—์„œ history.replace()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด

import React from 'react';
function Page2({ history }) {
  history.replace('/Page3');
  return <div>Page2</div>;
}
export default Page2;  

Home > Page1 > Page3 ์ˆœ์œผ๋กœ history์— ์Œ“์—ฌ, ๋งˆ์ง€๋ง‰ Page3์—์„œ ๋’ค๋กœ ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด Page1๋กœ ๋˜๋Œ์•„๊ฐ„๋‹ค.

์ฆ‰, history๋ฅผ ์Šคํƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์„ ๋•Œ push๋Š” ์Œ“์—ฌ ์žˆ๋Š” browser history ์œ„์— ์Œ“๋Š” ๊ฒƒ์ด๊ณ , replace๋Š” ์Œ“์—ฌ ์žˆ๋Š” history ์ œ์ผ ์œ„์˜ ์š”์†Œ์™€ ํ˜„์žฌ ๋„ฃ๋Š” ์š”์†Œ๋ฅผ ๋ง ๊ทธ๋Œ€๋กœ replace(๋Œ€์ฒด)ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

window.history๋Š” ์ž„์˜๋กœ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค.
๋Œ€์‹ ์— history๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”๋ฐ, ๋ฐ”๋กœ Router.replace ๊ฐ์ฒด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋กœ๊ทธ์ธ ์˜ˆ์‹œ

๋งŒ์•ฝ, ๋กœ๊ทธ์ธ ํ›„ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ์–ด๋–ค ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ด์•ผ ํ• ๊นŒ?
๋กœ๊ทธ์ธ ์ƒํƒœ๋Š” ์œ ์ง€๋œ ์ฑ„ ๋กœ๊ทธ์ธ ํ™”๋ฉด์— ๋“ค์–ด์˜ค๊ธฐ ์ „ ํ™”๋ฉด(home)์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด ๋งค๋„๋Ÿฌ์šธ ๊ฒƒ์ด๋‹ค.
์ด๋Ÿด ๋•Œ Router.replace ๊ฐ์ฒด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • push
    ํ™ˆ > ๋กœ๊ทธ์ธ > ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํŽ˜์ด์ง€ > [๋’ค๋กœ๊ฐ€๊ธฐ] > ๋กœ๊ทธ์ธ
import React from 'react';
function Login({ history }) {
  history.push('/item');
  return <div>Login</div>;
}
export default Login;

-> push๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ํžˆ์Šคํ† ๋ฆฌ๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์Œ“์—ฌ์„œ, ๋กœ๊ทธ์ธ์˜ ๋‹ค์Œ ํŽ˜์ด์ง€์—์„œ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐ€๊ฒŒ ๋œ๋‹ค.

  • replace
    ํ™ˆ > ๋กœ๊ทธ์ธ > ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํŽ˜์ด์ง€ > [๋’ค๋กœ๊ฐ€๊ธฐ] > ํ™ˆ
import React from 'react';
function Login({ history }) {
  history.replace('/item');
  return <div>Login</div>;
}
export default Login;

-> replace๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด history ์ œ์ผ ์œ„์— ์žˆ๋Š” ์›์†Œ๋ฅผ ์ง€๊ธˆ ๋„ฃ์„ ์›์†Œ๋กœ ๋ฐ”๊ฟ”์ค˜์„œ, ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋กœ๊ทธ์ธ์˜ ์ „ ํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐ€๊ฒŒ ๋œ๋‹ค.
replace๋Š” ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•œ๋‹ค๊ธฐ ๋ณด๋‹ค๋Š” ํ˜„์žฌ ํŽ˜์ด์ง€๋ฅผ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฐœ๋…์ด๋‹ค.

2. ๋ผ์šฐํ„ฐ ๊ฐ์ฒด์˜ pathname๊ณผ asPath์˜ ์ฐจ์ด์  : ํด๋”๊ตฌ์กฐ์™€ ํŽ˜์ด์ง€์ฃผ์†Œ(์‹ค์ œ์ฃผ์†Œ)

https://velog.io/@e_juhee/router-pathname
https://im-designloper.tistory.com/102

3. React์™€ Next์˜ Router์˜ ์ฐจ์ด์ 

https://velog.io/@moony_moon/React-Next-Router-vs-React-Router


๐Ÿ’ก๋น„๋™๊ธฐ ํ†ต์‹ ๊ณผ ์กฐ๊ฑด๋ถ€๋ Œ๋”๋ง

javascript๋Š” ์ž‘์„ฑ๋œ ์ฝ”๋“œ๊ฐ€ ์ƒ๋‹จ์—์„œ๋ถ€ํ„ฐ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„์˜ค๋Š” ๋™์•ˆ ํ™”๋ฉด์— ๊ทธ๋ ค์งˆ ๋ฐ์ดํ„ฐ์˜ ๋‚ด์šฉ์ด undefined ์ด๋ฏ€๋กœ ์ฒซ ํ™”๋ฉด์ด ๊ทธ๋ ค์ง€๋Š” ์‹œ๊ธฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋ฉด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ด ๋ถ€๋ถ„์ด ํšจ์œจ์ ์œผ๋กœ ์‹คํ–‰๋˜๊ธฐ ์œ„ํ•ด์„œ ํ™”๋ฉด์„ ๋ฏธ๋ฆฌ ๊ทธ๋ ค๋†“๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด์„œ ์กฐ๊ฑด๋ถ€๋ Œ๋”๋ง์„ ์‚ฌ์šฉํ•œ๋‹ค.


์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์˜ ์ข…๋ฅ˜๋กœ๋Š” &&์—ฐ์‚ฐ์ž, ์‚ผํ•ญ์—ฐ์‚ฐ์ž, ์˜ต์…”๋„์ฒด์ด๋‹์ด ์žˆ๋‹ค.

โœ… ์‚ผํ•ญ ์—ฐ์‚ฐ์ž

์ œ์ผ ์ฒ˜์Œ์—๋Š” ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์ผ๋‹ค.
data๋Š” ๋™๊ธฐ์ ์œผ๋กœ ๋ฐ›์•„์™€์•ผํ•˜๋Š” ๋ฐ์ดํ„ฐ์ง€๋งŒ,
๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๊ธฐ ์ „์— ์ด๋ฏธ return ๋ถ€๋ถ„์—์„œ rendering์„ ํ•ด์ฃผ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—
์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์จ์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์„ ๋•Œ, ์—†์„ ๋•Œ๋ฅผ ๋ชจ๋‘ ์ ์–ด์ค˜์•ผํ–ˆ๋‹ค.

์‚ผํ•ญ์—ฐ์‚ฐ์ž๋Š” 3๊ฐœ์˜ ํ”ผ์—ฐ์‚ฐ์ž๋ฅผ ์ทจํ•œ๋‹ค.
์กฐ๊ฑด ? ์ฐธ(๊ฐ’ ๋˜๋Š” ์‹) : ๊ฑฐ์ง“(๊ฐ’ ๋˜๋Š” ์‹)

data ? data.fetchProfile : undefined

โœ… && ์—ฐ์‚ฐ์ž

๊ทธ ์ดํ›„ && ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

data && data.fetchProfile //์žˆ์„ ๋•Œ ๋ณด์—ฌ์ค˜๋ผ

&&์—ฐ์‚ฐ์ž๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.
๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๋•Œ ๋”ฐ๋กœ div๋ฅผ ์“ธ ํ•„์š”๊ฐ€ ์—†์œผ๋ฉด else ๋ถ€๋ถ„์„ ์“ธ ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ ์ด ์ฝ”๋“œ์กฐ์ฐจ ๊ธธ๋‹ค๊ณ  ๋Š๊ปด์ง„๋‹ค.

&&์—ฐ์‚ฐ์ž๋Š” ์•ž์˜ ๊ฐ’์ด ์ฐธ์ผ ๊ฒฝ์šฐ์—๋งŒ ๋’ค์˜ ๊ฐ’์„ ๋ณด์—ฌ์ฃผ์—ˆ๋Š”๋ฐ, ๋ฐ˜๋Œ€๋กœ ์•ž์˜ ๊ฐ’์ด ๊ฑฐ์ง“์ผ๋•Œ ๋’ค์˜ ๊ฐ’์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค. Nullish coalescing ์—ฐ์‚ฐ์ž๋ผ ๋ถˆ๋ฆฐ๋‹ค.
nullish-coalescing : null๊ณผ ๋น„์Šทํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค(๋„์Šค๋Ÿฝ๋‹ค)

??์—ฐ์‚ฐ์ž๋Š” ์•ž์˜ ๊ฐ’์ด ๋นˆ ๊ฐ’์ด๋ฉด ๋’ค์˜ ๊ฐ’์„ ๋ณด์—ฌ์ฃผ๋ฉฐ ||์—ฐ์‚ฐ์ž๋Š” ์•ž์˜ ๊ฐ’์ด ๊ฑฐ์ง“(false)์ผ ๊ฒฝ์šฐ ๋’ค์˜ ๊ฐ’์„ ๋ณด์—ฌ์ค€๋‹ค.

data ?? data.fetchProfile
data || data.fetchProfile //๊ธฐ๋ณธ๊ฐ’์ฒ˜๋ฆฌ ์‹œ

โœ… ์˜ต์…”๋„ ์ฒด์ด๋‹ (Optional-Chaining)

optional-chaing์ด๋ž€ ๊ธฐ์กด์˜ && ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ๋ฉด์„œ ๊ธธ์–ด์กŒ๋˜ ์ฝ”๋“œ๋ฅผ ๋”์šฑ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ์—ฐ์‚ฐ์ž ์ด๋‹ค.

optional-chaing์€ ์ตœ์‹  ๋ฌธ๋ฒ•์œผ๋กœ ๋ฌด๋ ค ES2020์—์„œ ๋‚˜์˜จ ๊ฒƒ.
๊ทธ๋ž˜์„œ ์•„์ง ๋ชจ๋ฅด๋Š” ์‚ฌ๋žŒ์ด ๋งŽ์„ ์ˆ˜๋„ ์žˆ๋‹ค.

data?.fetchProfile

optional-Chaining์€ ? ์—ฐ์‚ฐ์ž ์•ž ๊ฐ์ฒด์˜ ์ฐธ์กฐ๊ฐ€ undefined || null ์ด๋ผ๋ฉด undefined๋ฅผ ๋ฆฌํ„ดํ•ด์ค€๋‹ค.

์‚ผํ•ญ์—ฐ์‚ฐ์ž, && ์—ฐ์‚ฐ์ž์™€ ๋˜‘๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๊ฑฐ์ง€๋งŒ ํ›จ์”ฌ ๊ฐ„๋‹จํ•ด์กŒ๋‹ค.

๊ทธ๋Ÿผ optional chaining ์ด ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ฃผ๋Š” ๊ฑธ๊นŒโ“
๊ธฐ๋‹ค๋ ค ์ฃผ๋Š”๊ฒŒ ์•„๋‹˜!
๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„๋•Œ๋Š” undefined๋ฅผ ๋ฆฌํ„ดํ–ˆ๋‹ค๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๋“ค์–ด์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ํ™”๋ฉด์„ ๋‹ค์‹œ ๋ Œ๋”ํ•ด์ฃผ๋Š” ๊ฒƒ.
์ด๊ฒƒ์„ ๋ฆฌ๋ Œ๋”๋ง์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

optional chaining ์–ธ์ œ ์‚ฌ์šฉํ• ๊นŒโ“
๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด์— ๋ Œ๋”๋ง ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
๋ฐฑ์—”๋“œ์™€ ํ†ต์‹ ํ•ด์„œ ๋ฐ›์•„์˜ค๋Š” ๋ฐ์ดํ„ฐ๋“ค์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์˜ต์…”๋„ ์ฒด์ด๋‹์„ ์‚ฌ์šฉํ•ด์•ผ ํ™”๋ฉด์— ์˜ค๋ฅ˜๊ฐ€ ์•ˆ๋‚˜๊ณ  ์ž˜ ๋ Œ๋”๋œ๋‹ค.

๐Ÿ’ก graphql ๋ฎคํ…Œ์ด์…˜์— try ~ catch ์ ์šฉ

mutation์ด ํ•ญ์ƒ ์„ฑ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค

Backend ์ปดํ“จํ„ฐ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๋‚ด๊ฐ€ ์ˆ˜์ •ํ•˜๋ ค๋Š” ๊ฒŒ์‹œ๋ฌผ์ด ๊ฐ‘์ž๊ธฐ ์‚ญ์ œ๊ฐ€ ๋˜๋Š” ๋ฐ”๋žŒ์— ์ˆ˜์ •์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์‹คํŒจ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ, ์šฐ๋ฆฌ๋Š” ์„ฑ๊ณต์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ, ์‹คํŒจ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋‚˜๋ˆ„์–ด ์ž‘์—…ํ•ด์•ผ ํ•œ๋‹ค.

try {
		await createBoard({
				variables: {
						aaa: "ํ›ˆ์ด",
						bbb: "1234",
						ccc: "์•ˆ๋…•ํ•˜์„ธ์š” ํ›ˆ์ด์—์š”",
						ddd: "๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค"
				}
		})
} catch(error) {
		alert(error.message)     // ๊ฒฝ๊ณ ์ฐฝ(์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.)  ==>  ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ณด๋‚ด์ฃผ๋Š” ์‹คํŒจ ๋ฉ”์‹œ์ง€
} finally {
	// ์„ฑ๊ณต, ์‹คํŒจ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ๋ฌด์กฐ๊ฑด ๋งˆ์ง€๋ง‰์— ์‹คํ–‰๋˜๋Š” ๋ถ€๋ถ„
	// ํ•„์š”์—†๋‹ค๋ฉด ์ƒ๋žต ๊ฐ€๋Šฅ
}

โ–ผ ์‹ค์Šต

//05-05-dynamic-routing-board-mutation
import { useMutation, gql } from "@apollo/client";
import { useRouter } from "next/router";
const ๋‚˜์˜๊ทธ๋ž˜ํ”„ํ์—˜์„ธํŒ… = 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(๋‚˜์˜๊ทธ๋ž˜ํ”„ํ์—˜์„ธํŒ…);
  const onClickSubmit = async () => {
    try {
      const result = await ๋‚˜์˜ํ•จ์ˆ˜({
        variables: {
          //variables๊ฐ€ $์—ญํ• ์„ ํ•œ๋‹ค.
          writer: "์ฒ ์ˆ˜",
          title: "hi",
          contents: "you",
        },
      });
      console.log(result);
      console.log(result.data.createBoard.number);
      // router.push("/section05/05-05-dynamic-routing-board-mutation-moved/" + result.data.createBoard.number)
      router.push(
        `/section05/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";
//playground์—์„œ ์—ฐ์Šตํ•˜๊ณ  ๋ณต๋ถ™
const FETCH_BOARD = gql`
  query fetchBoard($number: Int) {
    fetchBoard(number: $number) {
      number
      writer
      title
      contents
    }
  }
`;
export default function StaticRoutingPage() {
  const router = useRouter();
  console.log(router);
  const { data } = useQuery(FETCH_BOARD, {
    variables: {
      number: Number(router.query.number), //"๋ฌธ์ž์—ด" -> ์ˆซ์ž
    },
  });
  console.log(data); //์ž˜ ๋ฌ๋Š”์ง€ ์กฐํšŒํ•˜๊ธฐ
  return (
    <div>
      <div>2๋ฒˆ ์ด๋™์™„๋ฃŒ</div>
      <div>์ž‘์„ฑ์ž : {data && data?.fetchBoard?.writer}</div>
      <div>์ œ๋ชฉ : {data?.fetchBoard?.title}</div>
      <div>๋‚ด์šฉ : {data ? data?.fetchBoard?.contents : "๋กœ๋”ฉ์ค‘์ž…๋‹ˆ๋‹ค"}</div>
    </div>
  );
}

โœ… useQuery

-> const { data : qqq } = useQuery(FETCH_BOARD);
์ด๋ฆ„๋ฐ”๊ฟ€๋•Œ : ํ•ด์„œ ๋ฐ”๊ฟˆ.
์Šคํ…Œ์ดํŠธ์ฒ˜๋Ÿผ ๋งˆ์Œ๋Œ€๋กœ ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค.

โœ… shorthand property

shorthand property๋Š” ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•  ๋•Œ ๊ฐ์ฒด์˜ key๊ฐ’๊ณผ value ๊ฐ’์ด ๊ฐ™์œผ๋ฉด, ๊ฐ๊ฐ ํ‘œ๊ธฐํ•˜์ง€ ์•Š๊ณ  ํ•œ ๋ฒˆ๋งŒ ํ‘œ๊ธฐํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.


๐Ÿ“Œ ๊ณผ์ œ

freeboard

//----------------------------------------> import ํ•ด์˜ค๊ธฐ
import {
  Wrapper,
  Title,
  Wrapper_input,
  Wrapper_info,
  Name,
  NameInput,
  PwdInput,
  Password,
  Wrapper_title,
  Subtitle,
  Sub_Input,
  Wrapper_content,
  Content,
  Content_input,
  Wrapper_address,
  Address_title,
  AddressZip,
  Address_Input,
  Search_btn,
  Address,
  Wrapper_youtube,
  Youtube_title,
  Youtube_Input,
  Wrapper_image,
  Img_title,
  UploadBox,
  UploadBtn,
  Box,
  Plus,
  Text,
  Wrapper_mainSet,
  Main_title,
  Radio,
  RadioButton,
  RadioLabel,
  Wrapper_register,
  SubmitBtn,
  Color,
} from "../../styles/css";
import { useState } from "react";
import { useMutation, gql } from "@apollo/client";
import { useRouter } from "next/router";
//----------------------------------------> gql
const CREATE_BOARD = gql`
  mutation createBoard($writer: String, $title: String, $contents: String) {
    createBoard(writer: $writer, title: $title, contents: $contents) {
      _id
      number
      message
    }
  }
`;
//----------------------------------------> freeBoardFrom()
export default function freeBoardFrom() {
  const router = useRouter(); //------------------------> router์„ ์–ธ
  const [createBoard] = useMutation(CREATE_BOARD); //-----------> createBoard์„ ์–ธ
  const [TheName, setName] = useState("");
  const [ThePassword, setPassword] = useState("");
  const [TheSubtitle, setSubtitle] = useState("");
  const [TheContent, setContent] = useState("");
  const [NameError, setNameError] = useState("");
  const [PasswordError, setPasswordError] = useState("");
  const [SubtitleError, setSubtitleError] = useState("");
  const [ContentError, setContentError] = useState("");
//---------------------------------------->onChangeํ•ธ๋“ค๋Ÿฌ ํ•จ์ˆ˜
  function onChangeName(event) {
    setName(event.target.value);
    if (event.target.value !== "") {
      setNameError("");
    }
  }
  function onChangePassword(event) {
    setPassword(event.target.value);
    if (event.target.value !== "") {
      setPasswordError("");
    }
    if (String(event.target.value).length < 8) {
      setPasswordError("๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” 8์ž ์ด์ƒ์ž…๋‹ˆ๋‹ค.");
    }
  }
  function onChangeSubtitle(event) {
    setSubtitle(event.target.value);
    if (event.target.value !== "") {
      setSubtitleError("");
    }
  }
  function onChangeContent(event) {
    setContent(event.target.value);
    if (event.target.value !== "") {
      setContentError("");
    }
  }
 //---------------------------------------->Signup ๊ฒ€์ฆํ•˜๊ธฐ
  const Signup = async () => {
    //๊ฐ€์ž…ํ•˜๊ธฐ
    if (!TheName) {
      //๋นˆ๊ฐ’์ด๋ผ๋ฉด
      setNameError("์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    }
    if (!ThePassword) {
      setPasswordError("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    } else if (String(ThePassword) < 8) {
      setPasswordError("๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” 8์ž ์ด์ƒ์ž…๋‹ˆ๋‹ค.");
    }
    if (!TheSubtitle) {
      setSubtitleError("์ œ๋ชฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    }
    if (!TheContent) {
      setContentError("๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    }
    if (
      TheName &&
      ThePassword &&
      String(ThePassword).length > 8 &&
      TheSubtitle &&
      TheContent
    ) {
      //๋นˆ๊ฐ’์ด ์•„๋‹ˆ๋ผ๋ฉด
      alert("๊ฒŒ์‹œ๊ธ€์ด ๋“ฑ๋ก๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
      try {
        const result = await createBoard({
          variables: {
            //variables๊ฐ€ $์—ญํ• ์„ ํ•œ๋‹ค.
            writer: TheName,
            title: TheSubtitle,
            contents: TheContent,
          },
        });
        console.log(result);
        console.log(result.data.createBoard.number);
        router.push(`/freeboard-moved/${result.data.createBoard.number}`);
      } catch (error) {
        alert(error.message);
      }
    }
  };
// ----------------------------------------> JSX
  return (
    <Wrapper>
      <Title>๊ฒŒ์‹œ๋ฌผ๋“ฑ๋ก</Title>
      <Wrapper_input>
        <Wrapper_info>
          <Name>์ž‘์„ฑ์ž</Name>
          <NameInput
            type="text"
            placeholder="์ด๋ฆ„์„ ์ ์–ด์ฃผ์„ธ์š”"
            onChange={onChangeName}
          />
          <Color>{NameError}</Color>
        </Wrapper_info>
        <Wrapper_info>
          <Password>๋น„๋ฐ€๋ฒˆํ˜ธ</Password>
          <PwdInput
            type="password"
            placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”"
            onChange={onChangePassword}
          />
          <Color>{PasswordError}</Color>
        </Wrapper_info>
      </Wrapper_input>
      <Wrapper_title>
        <Subtitle>์ œ๋ชฉ</Subtitle>
        <Sub_Input
          type="text"
          placeholder="์ œ๋ชฉ์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”"
          onChange={onChangeSubtitle}
        />
        <Color>{SubtitleError}</Color>
      </Wrapper_title>
      <Wrapper_content>
        <Content>๋‚ด์šฉ</Content>
        <Content_input
          type="text"
          placeholder="์ œ๋ชฉ์„ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”"
          onChange={onChangeContent}
        />
        <Color>{ContentError}</Color>
      </Wrapper_content>
      <Wrapper_address>
        <Address_title>์ฃผ์†Œ</Address_title>
        <AddressZip>
          <Address_Input type="text" placeholder="07250"></Address_Input>
          <Search_btn>์šฐํŽธ๋ฒˆํ˜ธ ๊ฒ€์ƒ‰</Search_btn>
        </AddressZip>
        <Address />
        <Address />
      </Wrapper_address>
      <Wrapper_youtube>
        <Youtube_title>์œ ํŠœ๋ธŒ</Youtube_title>
        <Youtube_Input
          type="text"
          placeholder="๋งํฌ๋ฅผ ๋ณต์‚ฌํ•ด์ฃผ์„ธ์š”."
</Youtube_Input>
      </Wrapper_youtube>
      <Wrapper_image>
        <Img_title>์‚ฌ์ง„์ฒจ๋ถ€</Img_title>
        <UploadBox>
          <UploadBtn>
            <Box>
              <Plus>+</Plus>
              <Text>Upload</Text>
            </Box>
          </UploadBtn>
          <UploadBtn>
            <Box>
              <Plus>+</Plus>
              <Text>Upload</Text>
            </Box>
          </UploadBtn>
          <UploadBtn>
            <Box>
              <Plus>+</Plus>
              <Text>Upload</Text>
            </Box>
          </UploadBtn>
        </UploadBox>
      </Wrapper_image>
      <Wrapper_mainSet>
        <Main_title>๋ฉ”์ธ์„ค์ •</Main_title>
        <Radio>
          <RadioButton type="radio" id="youtube" name="radio-button" />
          <RadioLabel>์œ ํŠœ๋ธŒ</RadioLabel>
          <RadioButton type="radio" id="image" name="radio-button" />
          <RadioLabel>์‚ฌ์ง„</RadioLabel>
        </Radio>
      </Wrapper_mainSet>
      <Wrapper_register>
        <SubmitBtn onClick={Signup}>๋“ฑ๋กํ•˜๊ธฐ</SubmitBtn>
      </Wrapper_register>
    </Wrapper>
  );
}

freeboard-moved/[page]

import {
  Wrapper_Board,
  Wrapper_one,
  Wrapper_Header,
  Wrapper_Writer,
  Image,
  Writer,
  WriterBox,
  Day,
  IconBox,
  LocationBox,
  ClipBox,
  LocationImg,
  ClipImg,
  Wrapper_Body,
  Title,
  ContentImg,
  Content,
  Wrapper_Video,
  VideoImg,
  Wrapper_Footer,
  ChoiceBox,
  LikeBox,
  LikeImg,
  LikeCount,
  DisLikeBox,
  DisLikeImg,
  DisLikeCount,
  Wrapper_two,
  Wrapper_Btn,
  BtnBox,
  GotoListBtn,
  ReviseBtn,
  Wrapper_Comment,
  CommentTop,
  Comment_Title,
  CommentImg,
  Comment,
  StarBox,
  Star,
  CommentInputBox,
  CommentInput,
  LimitedBox,
  LimitedText,
  ResisterBtn,
  CommentBottom,
  Wrapper_Commented,
  Wrapper_Commented1,
  CommentedImg,
  Wrapper_commentedBox,
  CommentedBox1,
  CommentedBox,
  CommentedName,
  CommentedStar,
  IconsBox,
  PencilBox,
  Pencil,
  CloseBox,
  Close,
  CommentedContents,
  CommentedDate,
} from "../../../styles/[csspage]/css";
// import * as All from "../../../styles/[csspage]/css";
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
      like
      createdAt
    }
  }
`;
export default function freeBoardFrom() {
  const router = useRouter();
  console.log(router);
  const { data } = useQuery(FETCH_BOARD, {
    variables: {
      number: Number(router.query.page),
    },
  });
  console.log(data);
  return (
    <Wrapper_Board>
      <Wrapper_one>
        <Wrapper_Header>
          <Wrapper_Writer>
            <Image src="/img.png" />
            <WriterBox>
              <Writer>{data && data?.fetchBoard?.writer}</Writer>
              <Day>{data && data?.fetchBoard?.createdAt}</Day>
            </WriterBox>
          </Wrapper_Writer>
          <IconBox>
            <ClipBox>
              <ClipImg src="/Clip.png" />
            </ClipBox>
            <LocationBox>
              <LocationImg src="/location.png" />
            </LocationBox>
          </IconBox>
        </Wrapper_Header>
        <Wrapper_Body>
          <Title>{data && data?.fetchBoard?.title}</Title>
          <ContentImg src="/content.png" />
          <Content>{data && data?.fetchBoard?.contents}</Content>
        </Wrapper_Body>
        <Wrapper_Video>
          <VideoImg src="/video.png" />
        </Wrapper_Video>
        <Wrapper_Footer>
          <ChoiceBox>
            <LikeBox>
              <LikeImg src="/like.png" />
              <LikeCount>{data && data?.fetchBoard?.like}</LikeCount>
            </LikeBox>
            <DisLikeBox>
              <DisLikeImg src="/dislike.png" />
              <DisLikeCount>{data && data?.fetchBoard?.like}</DisLikeCount>
            </DisLikeBox>
          </ChoiceBox>
        </Wrapper_Footer>
      </Wrapper_one>
      <Wrapper_two>
        <Wrapper_Btn>
          <BtnBox>
            <GotoListBtn>๋ชฉ๋ก์œผ๋กœ</GotoListBtn>
            <ReviseBtn>์ˆ˜์ •ํ•˜๊ธฐ</ReviseBtn>
          </BtnBox>
        </Wrapper_Btn>
        <Wrapper_Comment>
          <CommentTop>
            <Comment_Title>
              <CommentImg src="/comment.png" />
              <Comment>๋Œ“๊ธ€</Comment>
            </Comment_Title>
            <StarBox>
              <Star src="/graystar.png" />
              <Star src="/graystar.png" />
              <Star src="/graystar.png" />
              <Star src="/graystar.png" />
              <Star src="/graystar.png" />
            </StarBox>
            <CommentInputBox>
              <CommentInput
                type="text"
                placeholder="๊ฐœ์ธ์ •๋ณด๋ฅผ ๊ณต์œ  ๋ฐ ์š”์ฒญํ•˜๊ฑฐ๋‚˜, ๋ช…์˜ˆ ํ›ผ์†, ๋ฌด๋‹จ ๊ด‘๊ณ , ๋ถˆ๋ฒ• ์ •๋ณด ์œ ํฌ์‹œ ๋ชจ๋‹ˆํ„ฐ๋ง ํ›„ ์‚ญ์ œ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด์— ๋Œ€ํ•œ ๋ฏผํ˜•์‚ฌ์ƒ ์ฑ…์ž„์€ ๊ฒŒ์‹œ์ž์—๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค."
              />
              <LimitedBox>
                <LimitedText>0/100</LimitedText>
                <ResisterBtn>๋“ฑ๋กํ•˜๊ธฐ</ResisterBtn>
              </LimitedBox>
            </CommentInputBox>
          </CommentTop>
          <CommentBottom>
            <Wrapper_Commented1>
              <CommentedImg src="/img.png" />
              <Wrapper_commentedBox>
                <CommentedBox1>
                  <CommentedBox>
                    <CommentedName>๋…ธ์›๋‘</CommentedName>
                    <CommentedStar>
                      <Star src="/star.png" />
                      <Star src="/star.png" />
                      <Star src="/star.png" />
                      <Star src="/graystar.png" />
                      <Star src="/graystar.png" />
                    </CommentedStar>
                  </CommentedBox>
                  <IconsBox>
                    <PencilBox>
                      <Pencil src="/pencil.png" />
                    </PencilBox>
                    <CloseBox>
                      <Close src="/close.png" />
                    </CloseBox>
                  </IconsBox>
                </CommentedBox1>
                <CommentedContents>
                  ์ง„์งœ ์œ ์ตํ•˜๊ณ  ์ •๋ง ํ•„์š”ํ•œ ์ •๋ณด์ธ ๊ฒƒ ๊ฐ™์•„์š”~! ์•ž์œผ๋กœ๋„ ์ข‹์€
                  ์ •๋ณด ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค~!
                </CommentedContents>
                <CommentedDate>2021.02.22</CommentedDate>
              </Wrapper_commentedBox>
            </Wrapper_Commented1>
            <Wrapper_Commented>
              <CommentedImg src="/img.png" />
              <Wrapper_commentedBox>
                <CommentedBox>
                  <CommentedName>๋•…์ง€</CommentedName>
                  <CommentedStar>
                    <Star src="/star.png" />
                    <Star src="/star.png" />
                    <Star src="/star.png" />
                    <Star src="/graystar.png" />
                    <Star src="/graystar.png" />
                  </CommentedStar>
                </CommentedBox>
                <CommentedContents>์ง„์งœ ์ข‹๋„ค์š”~ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค~!</CommentedContents>
                <CommentedDate>2021.02.22</CommentedDate>
              </Wrapper_commentedBox>
            </Wrapper_Commented>
            <Wrapper_Commented>
              <CommentedImg src="/img.png" />
              <Wrapper_commentedBox>
                <CommentedBox>
                  <CommentedName>์•ˆ์šฐ์—ฝ</CommentedName>
                  <CommentedStar>
                    <Star src="/star.png" />
                    <Star src="/star.png" />
                    <Star src="/star.png" />
                    <Star src="/graystar.png" />
                    <Star src="/graystar.png" />
                  </CommentedStar>
                </CommentedBox>
                <CommentedContents>
                  ์•ž์œผ๋กœ๋„ ์ข‹์€ ์ •๋ณด ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค~!
                </CommentedContents>
                <CommentedDate>2021.02.22</CommentedDate>
              </Wrapper_commentedBox>
            </Wrapper_Commented>
          </CommentBottom>
        </Wrapper_Comment>
      </Wrapper_two>
    </Wrapper_Board>
  );
}

Image



๐Ÿฅš MEMO

  1. [์ด ์•ˆ์— ์žˆ๋Š” ๊ฑธ ๋ณ€์ˆ˜๋กœ ๋ณด๊ฒ ๋‹ค๋Š” ์˜๋ฏธ์ž„.] - ๋™์ ๋ผ์šฐํŒ…
  2. import { useRouter } from "next/router" ํ•ด์˜ค๊ธฐ!
  3. ์‹คํŒจ๋ฅผ ์—ผ๋‘ํ•ด๋†“๊ณ  ์ž‘์—…ํ•ด์•ผํ•œ๋‹ค.
    try ์“ฐ๊ธฐ
    ๊ฐ€์žฅ ์ค‘์š”ํ•œ๊ฒƒ ํŠธ๋ผ์ดํ•ด๋ณด๊ณ  ์•ˆ๋˜๋ฉด ์บ์น˜๋กœ ์—๋Ÿฌ๋„์–ด์คŒ!
    ํŠธ๋ผ์ดํ•ด์„œ ์‹คํŒจํ•˜๋ฉด ์ฝ˜์†” ์‹คํ–‰๋„์ง€ ์•Š๊ณ  ์บ์น˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
  4. !๋ถ€์ •์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•œ ์กฐ๊ฑด๋ฌธ์„ ์ด์šฉํ•  ๊ฒƒ ํ˜น์€
    event๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์„œ ์•ˆ์—์„œ ์ž‘์—…ํ•˜๊ธฐ
  5. ์ฟผ๋ฆฌ์กฐํšŒ์‹œ return๊ฐ’๋„ ์ž…๋ ฅํ•ด์•ผํ•จ.
  6. gql๋ฐ”์ธ๋”ฉ ๋น ๋ฅด๋ฆฌ์ง€ ๋ง๊ฒƒ
  7. ๊ฒฝ๋กœ์„ค์ • ์ œ๋Œ€๋กœ ํ•  ๊ฒƒ!

๐Ÿฅš Problem & Solve

  1. ๋ผ์šฐํ„ฐ ํ‘ธ์‰ฌํ•  ๋•Œ router.push(/05/product-moved/${result.data.createProduct._id});
    ํ•ด์ค˜์•ผ ๋˜๋Š”๋ฐ page๋กœ ํ–ˆ์Œ.
    2.query fetchProduct($productId: ID) ํ”Œ๋ ˆ์ด๋ณด๋“œ ๊ทธ๋Œ€๋กœ ์•„์ด๋”” ๋„ฃ์–ด์ค˜์•ผ ํ•˜๊ณ  productId๋Š” P๊ฐ€ ์•„๋‹˜.
  2. variables: {
    productId: String(router.query.page),},
    });
    query๋กœ ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ์กฐํšŒํ•˜๋Š”๊ฑฐ๋‹ˆ๊นŒ!!!
  3. ์‹ค์Šต ์ค‘์— ์ฝ”๋“œ๋ฅผ ๋ถ„๋ช… ๋งž๊ฒŒ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ api์š”์ฒญ์‹œ ์ž๊พธ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค,,๋„คํŠธ์›Œํฌ๋กœ ๋“ค์–ด๊ฐ€์„œ ๋ด๋„ ๋ชจ๋ฅด๊ฒ ๊ณต,,์–ด์ œ์ฒ˜๋Ÿผ ํŒŒ์ผ์„ ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๊ฑด๊ฐ€ ์‹ถ์–ด์„œ vscode๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋‹ค์‹œ ์ผฐ๋Š”๋ฐ๋„ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ๊ฒฐ๊ตญ ๋ฉ˜ํ† ๋‹˜๊ป˜ ๋„์›€์„ ์ฒญํ–ˆ๋Š”๋ฐ, ์•Œ๊ณ ๋ณด๋‹ˆ ํŒŒ์ผ๋ช…์— ๊ณต๋ฐฑ์ด ์žˆ์–ด์„œ ์ƒ๊ธด ๋ฌธ์ œ์˜€๋‹ค,,,ใ…Ž
    ์–ด์ฉ์ง€ใ… 
    ํŒŒ์ผ๋ช… ์“ธ ๋•Œ ๊ณต๋ฐฑ ์กฐ์‹ฌํ•  ๊ฒƒ! ์œ ์˜ํ•˜์ž@.@

๐Ÿฅš ํ•œ ์ฃผ ํšŒ๊ณ 

์ด๋ฒˆ ์ฃผ๊ฐ„์€ ์›นํŽ˜์ด์ง€์˜ ํ•ต์‹ฌ์„ ๋ฐฐ์› ๋‹ค.
๊ต‰์žฅํžˆ ์ค‘์š”ํ•œ ํฌ์ธํŠธ๋ผ๋Š” ๊ฒƒ!!
๋จธ๋ฆฟ ์†์— ํ•˜๋‚˜ํ•˜๋‚˜ ์ž˜ ๋“ค์–ด์™€์•ผ ํ•˜๋Š”๋ฐ
์›Œ๋‚™ ๋งŽ์€ ๋‚ด์šฉ์ด๋ผ ๋‚ด๊ฐ€ ์™„๋ฒฝํžˆ ์ดํ•ดํ•œ ๊ฑธ๊นŒ? ์‹ถ์€ ์˜์‹ฌ์ด ๋“ค๊ธฐ๋„ ํ•œ๋‹ค,,
๋ฉ˜ํ† ๋‹˜๊ป˜์„œ ์ž๊ธฐ ์ž์‹ ๊ณผ ํƒ€ํ˜‘ํ•˜์ง€ ๋ง๋žฌ์œผ๋‹ˆ ์ด๋Ÿด ์ˆ˜๋ก ๋” ๊ณต๋ถ€ํ•ด์•ผ๊ฒ ์ง€
์›Œ๋‚™ ์ž๋ฆฌ์—์„œ ์ž˜ ์•ˆ ์ผ์–ด๋‚˜๋‹ค ๋ณด๋‹ˆ๊นŒ ๋ชฉ๊ณผ ์–ด๊นจ๊ฐ€ ๋งŽ์ด ๋ป๊ทผํ•˜๋‹ค.
๊ฑด๊ฐ•๊ด€๋ฆฌ๋„ ์ž˜ ํ•ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค.
์˜ค๋Š˜ ๊ณผ์ œ ์ค‘ ๊ฒŒ์‹œํŒ UI๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์žˆ์–ด,
ํ€ด์ฆˆ ๊ณผ์ œ๋ฅผ ๋ถ€์ง€๋Ÿฐํžˆ ํ•˜๊ณ  ๋„˜์–ด๊ฐ”๋‹ค.
๋‹ค๋ฅธ ํŽ˜์–ด๋ถ„ ๋•์— JSX๋ฅผ ๋” ๋นจ๋ฆฌ ๋๋‚ด๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ฒŒ๋ฌ๋‹ค.
ํ•˜๋‚˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ๋„˜์–ด๊ฐ€๋ ค๋Š” ์„ฑํ–ฅ ๋•Œ๋ฌธ์ธ์ง€
CSS๋„ ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ์ž‘์—…ํ•ด์„œ ๋” ์˜ค๋ž˜๊ฑธ๋ ธ๋˜ ๊ฒƒ์ด๋‹คใ… ใ… 
ํ•œ๋ฒˆ์— ์ž‘์—…ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋‹ˆ ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋ฌ๋‹ค!
์˜ค๋ฅ˜๋ฐœ์ƒ์‹œ ํ•ด๊ฒฐํ•˜๋Š” ๋ฌธ์ œ์— ๋Œ€ํ•ด์„œ๋„ ์•Œ๊ฒŒ๋ฌ๋Š”๋ฐ,
ํŠนํžˆ ๋„คํŠธ์›Œํฌ ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ถ€๋ถ„์ด ๊ณผ์ œ๋ฅผ ํ•˜๋ฉด์„œ๋„ ํฐ ๋„์›€์ด ๋ฌ๋‹ค.
์ปดํฌ๋„ŒํŠธ๋“ค์„ importํ•ด์˜ค๋Š” ๊ณผ์ •์ด ๋ฒˆ๊ฑฐ๋กœ์›Œ์„œ
import * All from ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์–ด ์ ์šฉ์„ ํ–ˆ๋Š”๋ฐ
์ž˜ ๋˜์ง€ ์•Š๋Š” ๊ฑธ ๋ณด๋‹ˆ,,ํ‹€๋ฆฐ ๋ฐฉ๋ฒ•์ธ๊ฐ€๋ณด๋‹ค^^
์ด ๋˜ํ•œ ๊ณง ๋ฐฐ์šฐ๊ฒŒ ๋˜๊ฒ ์ง€,,
๋‹ค์Œ์ฃผ๋ถ€ํ„ฐ๋Š” ๋งค์ฃผ ์ˆ˜์š”์ผ๋งˆ๋‹ค ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ…Œ์ŠคํŠธ๋„ ์ง„ํ–‰ํ•œ๋‹ค.
์•Œ๊ณ ๋ฆฌ์ฆ˜,,์•ฝํ•œ๋ฐ,,๊ฒƒ๋„ ๋งŽ์ด ํ’€์–ด๋ด์•ผ ๋Š˜๊ฒ ์ง€ใ… ใ… !!!
์‹œ๊ฐ„๊ด€๋ฆฌ๋ฅผ ์–ด๋–ค ์‹์œผ๋กœ ์งœ์•ผ ํ•  ์ง€ ์ถฉ๋ถ„ํžˆ ๊ณ ๋ฏผํ•ด์•ผ๊ฒ ๋‹ค

profile
JUST DO WHATEVER

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