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

  • ๋™๊ธฐ ์‹คํ–‰๊ณผ ๋น„๋™๊ธฐ ์‹คํ–‰
    • VSCODE์—์„œ ๋น„๋™๊ธฐ
      • REST-API์—์„œ ๋™๊ธฐ/๋น„๋™๊ธฐ ์‹คํ–‰
  • ํ˜ธ์ด์ŠคํŒ…(Hoisting)
  • apollo-client ์…‹ํŒ…ํ•˜๊ธฐ
    • _app.js์˜ ์ž‘๋™ ์›๋ฆฌ
    • apollo-client ๋กœ graphql ๋ฎคํ…Œ์ด์…˜ ์‹คํ–‰
    • graphql ๋ฎคํ…Œ์ด์…˜์— async / await ์ ์šฉ
  • URL, URI URN ์ฐจ์ด
  • ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

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

์ฝ”๋“œ์บ ํ”„



๐Ÿ’ก ๋™๊ธฐ ์‹คํ–‰๊ณผ ๋น„๋™๊ธฐ ์‹คํ–‰

โœ… ๋™๊ธฐ(๊ธฐ๋‹ค๋ฆฌ์ž) vs ๋น„๋™๊ธฐ(๊ธฐ๋‹ค๋ฆฌ์ง€ ๋ง์ž)

  • ๋น„๋™๊ธฐ ์‹คํ–‰: ์„œ๋ฒ„ ์ปดํ“จํ„ฐ์˜ ์ž‘์—…์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š” ํ†ต์‹ ์œผ๋กœ ์„œ๋ฒ„์— ์š”์ฒญ(๋“ฑ๋ก, ์ˆ˜์ •, ์‚ญ์ œ ๋“ฑ)์ด ์ €์žฅ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ์ž‘์—…์„ ์ง„ํ–‰ํ•œ๋‹ค.
  • ๋™๊ธฐ ์‹คํ–‰: ์„œ๋ฒ„ ์ปดํ“จํ„ฐ์˜ ์ž‘์—…์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋‹ค์Œ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ํ†ต์‹ ์ด๋‹ค.


    ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๊ธฐ ์œ„ํ•ด์„œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋ฉด API์š”์ฒญ์„ ๋ฐ›์€ ๋ฐฑ์—”๋“œ ์ปดํ“จํ„ฐ๋Š”
    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €์— ์‘๋‹ต์„ ๋Œ๋ ค์ค€๋‹ค.
    ์ด ๋•Œ, ๊ฒŒ์‹œ๊ธ€์„ ๋“ฑ๋ก ํ›„ ๊ฒŒ์‹œ๊ธ€์„ ๋ถˆ๋Ÿฌ์™”์„ ๋•Œ ๊ฒŒ์‹œ๊ธ€์ด ๋ถˆ๋Ÿฌ์™€์ง€์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

    ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ์š”์ฒญ ํ›„ ๋ฐฑ์—”๋“œ ์ปดํ“จํ„ฐ์— ์š”์ฒญ์„ ์ „์†กํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ์ฒ˜๋ฆฌ๋œ ํ›„ ๊ฒŒ์‹œ๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๊ณผ์ •์ด ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š”๋ฐ,
    ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ด์ „์— ๊ฒŒ์‹œ๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๊ณผ์ •์ด ์‹คํ–‰๋˜์–ด์ ธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
    ์ด๋Ÿฌํ•œ ์‹คํ–‰ ๋ฐฉ์‹์„ ๋น„๋™๊ธฐ ์‹คํ–‰์ด๋ผ๊ณ  ํ•œ๋‹ค.

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

๊ทธ๋ ‡๋‹ค๋ฉด ๋น„๋™๊ธฐ๋Š” ์–ธ์ œ ์“ฐ๋Š”๊ฑธ๊นŒโ“

์š”์ฒญ๋“ค์ด ์„œ๋กœ ๊ธฐ๋‹ค๋ฆด ํ•„์š”๊ฐ€ ์—†์„ ๋•Œ ์“ฐ์ธ๋‹ค!
์ฆ‰, ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์š”์ฒญ์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•ด ์ค„ ๋•Œ์— ์‚ฌ์šฉ๋œ๋‹ค!
์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฒŒ์ž„์„ ๋‹ค์šด๋ฐ›์œผ๋ฉด์„œ ์นดํ†กํ•˜๋Š” ๊ฒƒ ๋˜ํ•œ ๋น„๋™๊ธฐ์ด๋‹ค.

โœ… VSCODE์—์„œ ๋น„๋™๊ธฐ

<REST-API์—์„œ ๋™๊ธฐ/๋น„๋™๊ธฐ ์‹คํ–‰>

  • ๋น„๋™๊ธฐ ํ†ต์‹ 
function ํ•จ์ˆ˜์ด๋ฆ„() {
	const data = axios.get('https://koreanjson.com/posts/1')
	console.log(data) // Promise
}

์œ„ ์ฝ”๋“œ๋Š” ์š”์ฒญ๋œ ์‘๋‹ต์„ ๊ฐ€์ ธ์™€ ๋ฐ์ดํ„ฐ์— ์ €์žฅํ•˜๊ณ , ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ˜์†” ์ฐฝ์— ์ฐ์–ด์ฃผ๋„๋ก ์ž‘์„ฑ๋œ ์ฝ”๋“œ์ด๋‹ค.

REST-API์—์„œ ๋ฐ์ดํ„ฐ์˜ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์œ„ํ•ด axios๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ํ†ต์‹ ์„ ์‚ฌ์šฉํ–ˆ๊ณ ,
์ฝ”๋“œ๋Š” ์ƒ๋‹จ์—์„œ๋ถ€ํ„ฐ ์‹คํ–‰๋˜๋ฉด์„œ ๋ฐฑ์—”๋“œ ์ปดํ“จํ„ฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ์‘๋‹ต์„ ์ค€๋‹ค.

์ด ๋•Œ, ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ์ฝ˜์†”์ฐฝ์—๋Š” ๋ฆฌํ„ด๋œ Promise ๊ฐ์ฒด๊ฐ€ ๋ณด์—ฌ์ง€๊ฒŒ ๋œ๋‹ค.

Promise ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ์š”์ฒญ๋œ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๋ฐ›์•„์˜ค๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒโ“

์ฐธ๊ณ  PROMISE

  • ๋™๊ธฐ ํ†ต์‹ (async/awiat)
async function ํ•จ์ˆ˜์ด๋ฆ„() {
	const data = await axios.get('https://koreanjson.com/posts/1')
	console.log(data) // {id: 1, title: "์ •๋‹น์˜ ๋ชฉ์ ์ด๋‚˜ ํ™œ๋™์ด ...", ...}
}

๋น„๋™๊ธฐ ์‹คํ–‰ ๋ฐฉ์‹์—์„œ ๋™๊ธฐ ์‹คํ–‰ ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ๋Š” async/awiat์ด ํ•„์š”ํ•˜๋‹ค.

await๋Š” ๊ผญ async์™€ ํ•จ๊ป˜ ์ž‘์„ฑ๋˜์–ด์•ผ ํ•œ๋‹คโ—๏ธ

์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ž‘์„ฑํ•˜๋ฉด await์ด ์ž‘์„ฑ๋œ ๋ถ€๋ถ„์˜ ์ฝ”๋“œ ์‹คํ–‰์ด ์™„์ „ํžˆ ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” ํ•˜๋‹จ์˜ ์ฝ”๋“œ๋กœ ์‹คํ–‰์ด ๋„˜์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค.
์™„์ „ํžˆ ์™„๋ฃŒ๋œ ํ›„ ์™„์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ฝ˜์†” ์ฐฝ์— ์šฐ๋ฆฌ๊ฐ€ ๋ถˆ๋Ÿฌ์˜ค๊ณ ์ž ํ–ˆ๋˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž˜ ๋ณด์—ฌ์ง€๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
๊ฐ€๋งŒํžˆ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ๋„ฃ๋Š” ๊ฒƒ์„ ์‹คํ–‰ํ•˜์ง€ ๋งˆ๋ผ!
๋ฐ›์•„์˜ฌ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ๊ทธ ํ›„์— ๋ฐ›์•„์˜ค๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์ง‘์–ด๋„ฃ๊ฒŒ ๋œ๋‹ค.

โ–บ ์‹ค์Šตํ•ด๋ณด๊ธฐ

import axios from "axios";
import ๋‚˜๋งŒ์˜ํŽ˜์ด์ง€ from "../../section01/01-01-example";
export default function RestGetPage() {
  //js
  function onClickAsync() {
    const result = axios.get("https://koreanjson.com/posts/1");
    console.log(result); //Promise
  }
  //ํ•จ์ˆ˜ ์ค‘๋ณต ์„ ์–ธ ๋ฌธ์ œ๋กœ ํ™”์‚ดํ‘œํ•จ์ˆ˜๋กœ ๋ฐ”๊ฟˆ!
  // async function onClickSync(){
  // 	const result = await axios.get("https://koreanjson.com/posts/1")
  // 	console.log(result) //์ œ๋Œ€๋กœ ๋œ ๊ฒฐ๊ณผ =>{ title : "..." }
  // 	console.log(result.data.title) //์ •๋‹น์˜ ๋ชฉ์ ์ด๋‚˜...
  // }
	const onClickSync = async () => {
    const result = await axios.get("https://koreanjson.com/posts/1");
    console.log(result); //์ œ๋Œ€๋กœ ๋œ ๊ฒฐ๊ณผ =>{ title : "..." }
    console.log(result.data.title); //์ •๋‹น์˜ ๋ชฉ์ ์ด๋‚˜...
  };
  return (
    //jsx
    <div>
      <button onClick={onClickAsync}>REST-API(๋น„๋™๊ธฐ)์š”์ฒญํ•˜๊ธฐ</button>
      <button onClick={onClickSync}>REST-API(๋™๊ธฐ)์š”์ฒญํ•˜๊ธฐ</button>
      <๋‚˜๋งŒ์˜ํŽ˜์ด์ง€ />
    </div>
  );
}

โœ…ย Fragments
React์—์„œ DOM์— ๋ณ„๋„์˜ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ์—ฌ๋Ÿฌ ์ž์‹์„ ๊ทธ๋ฃนํ™” ํ•  ์ˆ˜ ์žˆ๋Š” ํƒœ๊ทธ๋กœ,
์‚ฌ์šฉ ์‹œ key๊ฐ€ ์—†๋‹ค๋ฉด <></> ์ฒ˜๋Ÿผ ๋นˆ ํƒœ๊ทธ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ,
๋งŒ์•ฝ key๊ฐ€ ์žˆ๋‹ค๋ฉด <Fragment></Fragment> ๋ฌธ๋ฒ•์œผ๋กœ ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•ด์ค˜์•ผ ํ•œ๋‹ค.

โ—๏ธย ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋™๊ธฐ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด์ง€๋งŒ,
์™ธ๋ถ€ ์„ค์น˜ํ”„๋กœ๊ทธ๋žจ์€ ๋Œ€๋ถ€๋ถ„ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด๋‘์–ด์„œ ์‹คํ–‰์‹œ์— ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰๋œ๋‹ค.


๐Ÿ’ก ํ˜ธ์ด์ŠคํŒ…(Hoisting)

โœ… ํ˜ธ์ด์ŠคํŒ…์ด๋ž€โ“

์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์„ ์–ธ ์ „์— ๋ฏธ๋ฆฌ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ
์‰ฝ๊ฒŒ ๋งํ•ด, ๋ณ€์ˆ˜์˜ ์„ ์–ธ๊ณผ ์ดˆ๊ธฐํ™”๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์„ ์–ธ๋งŒ ์ฝ”๋“œ์˜ ์ตœ์ƒ๋‹จ์œผ๋กœ ๋Œ์–ด์˜ฌ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.
๋”ฐ๋ผ์„œ, ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ์ฝ”๋“œ๋ณด๋‹ค ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์•ž์„œ ๋“ฑ์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ณ€์ˆ˜ ์„ ์–ธ ๋ฐฉ์‹ ์ค‘์— var๋Š” ์ด๋ฏธ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋ฅผ ๋‹ค์‹œ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฆ‰ ํ˜ธ์ด์ŠคํŒ…์ด ์ผ์–ด๋‚ฌ๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ณ€์ˆ˜ ์„ ์–ธ ๋ฐฉ์‹์ด๋‹ค.

  • ๋ณ€์ˆ˜ ์„ ์–ธ ๋ฐฉ์‹(var)์˜ ํ˜ธ์ด์ŠคํŒ…
console.log(num); // ํ˜ธ์ด์ŠคํŒ…ํ•œ var ์„ ์–ธ์œผ๋กœ ์ธํ•ด undefined ์ถœ๋ ฅ
var num; // ์„ ์–ธ
num = 6;  // ์ดˆ๊ธฐํ™”

๋ณ€์ˆ˜ ์„ ์–ธ ์‹œ ์ดˆ๊ธฐํ™”๋ฅผ ์ œ์™ธํ•œ ์„ ์–ธ๋งŒ ํ˜ธ์ด์ŠคํŒ…ํ•œ๋‹ค.
๋ณ€์ˆ˜๋ฅผ ๋จผ์ € ์‚ฌ์šฉํ•˜๊ณ  ๊ทธ ํ›„์— ์„ ์–ธ ๋ฐ ์ดˆ๊ธฐํ™”๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฉด ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์˜ ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ ์ดˆ๊ธฐํ™” ์ƒํƒœ์ธ undefined์ด๋‹ค.
let๊ณผ const๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋„ ํ˜ธ์ด์ŠคํŒ…์ด ๋˜๊ธด ํ•˜์ง€๋งŒ,
var์™€๋Š” ๋‹ฌ๋ฆฌ undefined๋กœ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜ ์„ ์–ธ ์ „์— ๋จผ์ € ์‚ฌ์šฉํ•˜๊ฒŒ๋˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.
  • ํ•จ์ˆ˜(function)์˜ ํ˜ธ์ด์ŠคํŒ…
catName('ํด๋กœ์ด')
function catName(name) {
	console.log('์ œ ๊ณ ์–‘์ด์˜ ์ด๋ฆ„์€' + name + '์ž…๋‹ˆ๋‹ค')'
}// '์ œ ๊ณ ์–‘์ด์˜ ์ด๋ฆ„์€ ํด๋กœ์ด์ž…๋‹ˆ๋‹ค'

ํ•จ์ˆ˜๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ํ•จ์ˆ˜ ์„ ์–ธ์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ('ํด๋กœ์ด')๋ถ€ํ„ฐ ํ• ๋‹น๋˜์–ด,
ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•จ์ˆ˜ ์„ ์–ธ ์•ž์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
์ด๋Ÿฌํ•œ ํŠน์ง• ๋•Œ๋ฌธ์— const๋ฅผ ์‚ฌ์šฉํ•œ ํ™”์‚ดํ‘œํ˜• ํ•จ์ˆ˜ ์„ ์–ธ ๋ฐฉ์‹์„ ํ†ตํ•ด ์˜ˆ์ƒํ•˜์ง€ ๋ชปํ•œ ์—๋Ÿฌ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰, ํ™”์‚ดํ‘œํ•จ์ˆ˜๋ฅผ ์“ฐ๊ฒŒ ๋˜๋ฉด ๋ณ€์ˆ˜์˜ ์ค‘๋ณต์„ ์–ธ์„ ๋ง‰์•„์ค€๋‹คโ—๏ธ


๐Ÿ’ก apollo-client ์…‹ํŒ…ํ•˜๊ธฐ

playground ์—์„œ ์‹ค์Šตํ–ˆ๋˜ ๋‚ด์šฉ์˜ ์ฝ”๋“œ๋ฅผ vscode์—์„œ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” apollo-client๋ผ๋Š” ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

apollo-client๋ฅผ ์„ค์น˜ ํ›„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ฒ˜์Œ 1๋ฒˆ ์…‹ํŒ…์ด ํ•„์š”ํ•œ๋ฐ,
์„ค์น˜ํ•œ ๋„๊ตฌ๋“ค์„ ์…‹ํŒ…ํ•˜๋Š” ์œ„์น˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ _app.js ์— ์žˆ๋‹ค.

_app.js์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ค€๋‹ค.


โœ… _app.js์˜ ์ž‘๋™ ์›๋ฆฌ

index.js๊ฐ€ ํŽ˜์ด์ง€๋กœ ์ธ์‹๋˜์–ด ์‹คํ–‰๋˜๊ธด ํ•˜์ง€๋งŒ,
์‚ฌ์‹ค์€ index.js(ํŽ˜์ด์ง€)๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ index.js๊ฐ€ app.js๋กœ ํ•ฉ์ณ์ ธ์„œ app.js๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด๋‹ค.

import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client"; // InMemoryCache์— ์ž„์‹œ์ €์žฅ
export default function App({ Component }) {
  const client = new ApolloClient({
    uri: "http://backend-example.codebootcamp.co.kr/graphql",
    cache: new InMemoryCache(), //์ปดํ“จํ„ฐ์˜ ๋ฉ”๋ชจ๋ฆฌ(rem)์— ๋ฐฑ์—”๋“œ์—์„œ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ ๋ชจ๋‘ ์ž„์‹œ์ €์žฅ!
  });
return (
    <div>
      <div> ==== ์—ฌ๊ธฐ๋Š” _app.js ์ปดํฌ๋„ŒํŠธ ์‹œ์ž‘๋ถ€๋ถ„</div>
      <ApolloProvider client={client}>
        <Component />
      </ApolloProvider>
      <div> ==== ์—ฌ๊ธฐ๋Š” _app.js ์ปดํฌ๋„ŒํŠธ ๋งˆ์ง€๋ง‰๋ถ€๋ถ„</div>
    </div>
  );
}

ํŽ˜์ด์ง€์ปดํฌ๋„ŒํŠธ๋„ ๋ถˆ๋Ÿฌ์™€์„œ ์กฐ๋ฆฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค (์™œ๋ƒ? ํŽ˜์ด์ง€๋„ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€ํ’ˆ์ด๋ผ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค!) -> ์ด์ฒ˜๋Ÿผ ํŽ˜์ด์ง€์ปดํฌ๋„ŒํŠธ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์žˆ๋Š” ๊ฒƒ์ด ์‹คํ–‰๋œ๋‹ค.
์ปดํฌ๋„ŒํŠธ ๋•Œ๋ฌธ์— ์–ด๋–ค ํŽ˜์ด์ง€๋ฅผ ์ ‘์†ํ•ด๋„ ๋ณด์ด๊ฒŒ ๋œ๋‹ค.
APP ์ปดํฌ๋„ŒํŠธ์— ๋ชจ๋“ ๊ฒŒ ํ•ฉ์ณ์ ธ์„œ ์‹คํ–‰์ด ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
(๋‚˜๋งŒ์˜ ํŽ˜์ด์ง€๊ฐ€ ๋ถˆ๋ ค์™€์„œ ํ•ฉ์ณ์ง„๋‹ค.)

๊ฒฐ๋ก โ—๏ธ
Component ์ž๋ฆฌ์— index.js๊ฐ€ ๋“ค์–ด์˜ค๊ฒŒ ๋˜๊ณ  index.js๊ฐ€ ํ•ฉ์ณ์ง„ app.js๊ฐ€ ์‹คํ–‰๋˜์–ด ์ตœ์ข…์ ์œผ๋กœ ์šฐ๋ฆฌ ๋ˆˆ์— ๋ณด์ด๋Š” ๊ฒƒ!


โœ… apollo-client ๋กœ graphql ๋ฎคํ…Œ์ด์…˜ ์‹คํ–‰

  1. playground์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋ ค๋Š” mutation์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  2. ์ œ๋Œ€๋กœ ์ž‘๋™ํ•œ๋‹ค๋ฉด, graphql mutation์„ ์‹คํ–‰ํ•˜๋ ค๋Š” ํŽ˜์ด์ง€ ์ƒ๋‹จ์—์„œ, apollo-client ์˜ ๋„๊ตฌ๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
// graphql ์š”์ฒญ์— ํ•„์š”ํ•œ ๋„๊ตฌ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
import { useMutation, gql } from '@apollo/client'
  1. javascript ์ž…๋ ฅ ๋ถ€๋ถ„์— playground์˜ ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์ด gql`` ์‚ฌ์ด์— ๋ถ™์—ฌ๋„ฃ์–ด ๋ณ€์ˆ˜/์ƒ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์ค€๋‹ค.
import { useMutation, gql } from "@apollo/client";
const ๋‚˜์˜๊ทธ๋ž˜ํ”„ํ์—˜์„ธํŒ… = gql`
  mutation {
    CREATE_BOARD(
      writer: "123", 
      title: "hi", 
      contents: "you"
    ){
      _id
      number
      message
    }
  }
`;

4.gql ๋ณ€์ˆ˜/์ƒ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ, useMutation์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค.

//mutation ์ฝ”๋“œ ์ƒ์„ฑ
const [๋‚˜์˜ํ•จ์ˆ˜(๋ณ€์ˆ˜๋ช…)] = useMutation(๋‚˜์˜๊ทธ๋ž˜ํ”„ํ์—˜์„ธํŒ…);

-> ๋ณดํ†ต API ์ด๋ฆ„๊ณผ ๋งž์ถฐ์„œ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ผ๋ฐ˜์ ์ด๋ฏ€๋กœ API ์ด๋ฆ„๊ณผ ํ†ต์ผํ•ด์„œ ์ ์–ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹คโ—๏ธ

5. ๊ฒŒ์‹œ๋ฌผ ๋“ฑ๋ก ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์—์„œ mutation ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด์ค€๋‹ค.

const onClickSubmit = () => {
 	const result = ๋‚˜์˜ํ•จ์ˆ˜();
  console.log(result);
};
//ํ•œ ์ค„์ผ ๋•Œ๋Š” (๊ด„ํ˜ธ) ํ•„์š”์—†์Œ
return <button onClick={onClickSubmit}>Graphql-API ์š”์ฒญํ•˜๊ธฐ</button>;
}


6. ๊ฒŒ์‹œ๋ฌผ์ด ์ •์ƒ์ ์œผ๋กœ ๋“ฑ๋ก๋˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์œ„ ๊ฐ™์€ ์ฝ”๋“œ๋Š” ํ•ญ์ƒ ๊ฐ™์€ ๊ฒŒ์‹œ๋ฌผ์ด ๋“ฑ๋ก๋œ๋‹ค๋Š” ๋ฌธ์ œ์ ์ด ์žˆ๊ณ , ์ด๋ฅผ ํ•˜๋“œ์ฝ”๋”ฉ ํ–ˆ๋‹ค๋ผ๊ณ  ํ•œ๋‹ค.
๋”ฐ๋ผ์„œ, CREATE_BOARD ๋ถ€๋ถ„์„ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.(CREATE_BOARD๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•œ๋‹ค ๊ด€๋ก€๊ฐ™์€ ๊ฒƒ)

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ๋Œ€๋กœ ์ƒ์„ฑํ•ด์ค˜์•ผ ํ•˜๊ธฐ๋•Œ๋ฌธ์— ์ž…๋ ฅ ๊ฐ’์ด ๋งค๋ฒˆ ๋ฐ”๋€Œ์–ด์•ผ ํ•œ๋‹ค!

input์˜ onChange๋ฅผ ์ด์šฉํ•ด ์ž…๋ ฅ๋ฐ›์€ ๊ฐ’์„ state์— ์ €์žฅ๋‘์—ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ,
์ž…๋ ฅ๋ฐ›์€ ๊ฐ’์„ state์— ์ €์žฅํ•˜๊ณ  variables($)์— ๋„ฃ์–ด์ค€๋‹ค.

import { useMutation, gql } from "@apollo/client";
// graphql ์ฝ”๋“œ
  const CREATE_BOARD = gql`
  mutation createBoard($writer: String, $title: String, $contents: String) { 
    createBoard(writer: $writer, title: $title, contents: $contents) {
      _id
      number
      message
    }
  }
`;

-> createBoard($ writer:String, $ title:String,$contents:String)์€ ํƒ€์ž…๊ฒ€์‚ฌ(ํ™•์ธ)์šฉ์ž„ ์‹ ๊ฒฝ์•ˆ์จ๋„ ๋จ.
ํ•˜์ง€๋งŒ ์“ฐ์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.

//mutation ์ฝ”๋“œ
export default function GraphqlMutationPage() {
  const [๋‚˜์˜ํ•จ์ˆ˜] = useMutation(CREATE_BOARD);
  const onClickSubmit = () => {
    const result = ๋‚˜์˜ํ•จ์ˆ˜({
      variables($): {
        //variables๊ฐ€ $์—ญํ• ์„ ํ•œ๋‹ค.
        writer: "์ฒ ์ˆ˜", 
      	title: "์ œ๋ชฉ", 
      	contents: "๋‚ด์šฉ"
      },
    });
    console.log(result);
  };
  //ํ•œ ์ค„์ผ ๋•Œ๋Š” (๊ด„ํ˜ธ) ํ•„์š”์—†์Œ
  return <button onClick={onClickSubmit}>Graphql-API ์š”์ฒญํ•˜๊ธฐ</button>;
}

์ฆ‰, graphql์— ์ž…๋ ฅํ•  ๋ฐ์ดํ„ฐ๋Š” ์ตœ์ข…์ ์œผ๋กœ ๋“ฑ๋กํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ, ์‹คํ–‰๋˜๋Š” onClickSubmit ํ•จ์ˆ˜์—์„œ ์‹คํ–‰๋˜๋Š” mutation ์—์„œ ๋„ฃ์–ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

โ—๏ธmutation์— ๋ณด๋‚ด์ค˜์•ผ ํ•  ๊ฐ’์„ ์ง์ ‘ ์ž…๋ ฅํ•˜๋Š” ๋ฐฉ์‹(3๋ฒˆ, 5๋ฒˆ ๊ณผ์ •)์„ โ€˜ํ•˜๋“œ์ฝ”๋”ฉโ€™์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

7. ๋งŒ์•ฝ ์ด๋ ‡๊ฒŒ ํ•ด๋„ ๊ณ„์† ๋˜‘๊ฐ™์€ ๋ฐ์ดํ„ฐ๋งŒ ๋“ค์–ด๊ฐ„๋‹ค๋ฉด?

  //mutation ์ฝ”๋“œ
export default function GraphqlMutationPage() {
  const [writer, setWriter] = useState(""); ------->๋ณ€๊ฒฝ
  const [title, setTitle] = useState(""); ------->๋ณ€๊ฒฝ
  const [contents, setContents] = useState(""); ------> ๋ณ€๊ฒฝ
  const [๋‚˜์˜ํ•จ์ˆ˜] = useMutation(CREATE_BOARD);
  const onClickSubmit = () => {
    const result = ๋‚˜์˜ํ•จ์ˆ˜({
      variables: {
        //variables๊ฐ€ $์—ญํ• ์„ ํ•œ๋‹ค($๋ถ™์—ฌ์•ผ ๋ณ€์ˆ˜๋ผ๋Š” ๊ฑธ ์•ˆ๋‹ค.)
        write: writer, -------------->๋ณ€๊ฒฝ
        title: title,-------------->๋ณ€๊ฒฝ
        contents: contents,------------>๋ณ€๊ฒฝ
      },
    });
    console.log(result);
  };
  //ํ•œ ์ค„์ผ ๋•Œ๋Š” (๊ด„ํ˜ธ) ํ•„์š”์—†์Œ
  return <button onClick={onClickSubmit}>Graphql-API ์š”์ฒญํ•˜๊ธฐ</button>;
}

-> variables์— ๋“ค์–ด๊ฐ€๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ ์ •๋œ ๊ฐ’์ด ์•„๋‹Œ, state๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์ตœ์ข…์ ์ธ ์ฝ”๋“œ๊ฐ€ ์™„์„ฑ๋œ๋‹ค

โœ… graphql ๋ฎคํ…Œ์ด์…˜์— async / await ์ ์šฉ

rest-API ๋˜๋Š” graphql-API ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ๋ฐ›์€ ๊ฐ์ฒด(JSON)๋ฅผ ๋ณ€์ˆ˜์— ๋‹ด์•„์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
์‘๋‹ต ๊ฒฐ๊ณผ๋ฅผ ๋ณ€์ˆ˜์— ๋‹ด์•„์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด!
ํ†ต์‹ ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š”๋ฐ,
์ด ๋•Œ async / await๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ๋‹ค.

<๊ธฐ๋ณธํ˜•์‹>

// ๋น„๋™๊ธฐ ํ†ต์‹ 
function ํ•จ์ˆ˜๋ช…() {
	// ์„œ๋ฒ„์— ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ
}
// ๋™๊ธฐ ํ†ต์‹ 
async function ํ•จ์ˆ˜๋ช…() {
	await // ์„œ๋ฒ„์— ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ
}
------------------------------------------------------
// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์ธ ๊ฒฝ์šฐ async ์˜ ์œ„์น˜๋ฅผ () ์•ž์— ์ž…๋ ฅํ•œ๋‹ค.
const ํ•จ์ˆ˜๋ช… = async () => {
	await // ์„œ๋ฒ„์— ์š”์ฒญํ•˜๋Š” ์ฝ”๋“œ
}
// mutation์— ๋™๊ธฐ์‹ ์ฒ˜๋ฆฌ
async function onClickSubmit(){
const result = await createBoard({
	variables: {
  		 writer: writer,
        title: title,
        contents: contents,
	}
  });
// ๊ฒฐ๊ณผ๋ฌผ ํ™•์ธํ•˜๊ธฐ
		console.log(result);
}
return <button onClick={onClickSubmit}>Graphql-API ์š”์ฒญํ•˜๊ธฐ</button>

โœ… graphql mutation-input ์‹ค์Šต

import { useMutation, gql } from "@apollo/client";
import { useState } from "react";
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 [writer, setWriter] = useState("");
  const [title, setTitle] = useState("");
  const [contents, setContents] = useState("");
  const [๋‚˜์˜ํ•จ์ˆ˜] = useMutation(๋‚˜์˜๊ทธ๋ž˜ํ”„ํ์—˜์„ธํŒ…);
  const onClickSubmit = async () => {
    const result = await ๋‚˜์˜ํ•จ์ˆ˜({
      variables: {
        //variables๊ฐ€ $์—ญํ• ์„ ํ•œ๋‹ค.
        writer: writer,
        title: title,
        contents: contents,
      },
    });
    console.log(result);
  };
  function onChangeWriter(event) {
    setWriter(event.target.value);
  }
  function onChangeTitle(event) {
    setTitle(event.target.value);
  }
  function onChangeContents(event) {
    setContents(event.target.value);
  }
  //ํ•œ ์ค„์ผ ๋•Œ๋Š” (๊ด„ํ˜ธ) ํ•„์š”์—†์Œ
  return (
    <div>
      ์ž‘์„ฑ์ž: <input type="text" onChange={onChangeWriter} />
      ์ œ๋ชฉ: <input type="text" onChange={onChangeTitle} />
      ๋‚ด์šฉ: <input type="text" onChange={onChangeContents} />
      <button onClick={onClickSubmit}>Graphql-API ์š”์ฒญํ•˜๊ธฐ</button>
    </div>
  );
}

โœ… graphql mutation-Product ์‹ค์Šต

import { useMutation, gql } from "@apollo/client";
const CREATE_PRODUCT = gql`
  mutation createProduct(
    $seller: String
    $createProductInput: CreateProductInput!
  ) {
    createProduct(seller: $seller, createProductInput: $createProductInput) {
      _id
      number
      message
    }
  }
`;
export default function GraphqlMutationPage() {
	const [createProduct] = useMutation(CREATE_PRODUCT);
  	const onClickSubmit = async () => {
    const result = await createProduct({
      variables: {
        //variables๊ฐ€ $์—ญํ• ์„ ํ•œ๋‹ค.
        seller: "์ฒ ์ˆ˜",
        createProductInput: {
          name: "mouse",
          detail: "good mouse",
          price: 2000,
        },
      },
    });
    console.log(result);
  };
  //ํ•œ ์ค„์ผ ๋•Œ๋Š” (๊ด„ํ˜ธ) ํ•„์š”์—†์Œ
  return <button onClick={onClickSubmit}>Graphql-API ์š”์ฒญํ•˜๊ธฐ</button>;
}

โœ… <GRAPHQL-API ์—ฐ์Šต>


๐Ÿ’ก URL, URI, URN ์ฐจ์ด

  • URL : ๋„คํŠธ์›Œํฌ ์ƒ์—์„œ ์›น ํŽ˜์ด์ง€, ์ด๋ฏธ์ง€, ๋™์˜์ƒ ๋“ฑ์˜ ํŒŒ์ผ์ด ์œ„์น˜ํ•œ ์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  • URN(Uniform Resource Name) : ๋ฆฌ์†Œ์Šค์˜ name์„ ๊ฐ€๋ฆฌํ‚ค๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.
  • URI : URL๊ณผ URN์„ ํฌํ•จํ•˜๋Š” ๊ฐœ๋…
  • " # ": ๋งŒ์•ฝ ํŽ˜์ด์ง€ ์ ‘์†ํ•˜์ž๋งˆ์ž ํ•˜๋‹จ์œผ๋กœ ๊ฐ€๊ณ  ์‹ถ๋‹ค๋ฉด (์ฃผ์†Œ)#footer
    [์ฐธ๊ณ ] URL, URI, URN

๐Ÿšจ ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

๋ฐ์ดํ„ฐ ํ†ต์‹  ๊ณผ์ •์ด ์—†๋‹ค๋ฉด ์˜ค๋ฅ˜๋ฐœ์ƒ ์‹œ ์ฝ˜์†”์ฐฝ์—์„œ ๋ฌธ์ œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฐ์ดํ„ฐ ํ†ต์‹  ๊ณผ์ •์ด ์ƒ๊ธด๋‹ค๋ฉด ์ฝ˜์†”์ฐฝ์—์„œ๋Š” ํ™•์ธํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๋“ค์ด ๋ฐœ์ƒํ•œ๋‹ค.
๋งค๋ฒˆ ์ˆ˜์ •ํ•˜๊ณ  refresh ํ•˜๋Š” ๊ฒƒ์€ ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•!
๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐ”๊พธ๊ณ  ๋‚˜์„œ ์ฝ”๋“œ๋กœ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค.

Request, Response, Preview ํ—ค๋”๋ฅผ ๊ฐ๊ฐ ํ™•์ธํ•˜์—ฌ ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋Š”์ง€ ์ง์ ‘ ํ™•์ธํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

<ํ•ด๊ฒฐ๋ฐฉ๋ฒ•>

1. HTML/ CSS ์—์„œ ๋ฐœ์ƒํ–ˆ์„ ์‹œ

  • ๊ฐœ๋ฐœ์ž ๋„๊ตฌ element ํƒญ์„ ํ™•์ธ ํ•  ๊ฒƒ
  • vs ์ฝ”๋“œ๋Š” ์ตœ์ข…์ž„!

2. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ์‹œ

  • ๋จผ์ € ์ฝ˜์†” ์ฐฝ์—์„œ ํ™•์ธํ•ด๋ณธ๋‹ค.
  • ๋ฒ„ํŠผ ํด๋ฆญํ•˜๊ณ  ๋„คํŠธ์›Œํฌ๋กœ ํ™•์ธํ•˜๊ธฐ

3. ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ์‹œ

  • request์™€ response์˜ ์†ก์ˆ˜์‹  ์ž˜ ๋˜๋Š”์ง€ ํ™•์ธ
  • payroad๋กœ ๋‚ด๊ฐ€ ์–ด๋–ค ๊ฑธ ๋ณด๋ƒˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
    (vscode๋กœ ์ž‘์—…ํ•œ ๊ฒƒ์ด๋‹ˆ ํ•„์ˆ˜ ํ™•์ธํ•  ๊ฒƒ!)

๐Ÿ“Œ ๊ณผ์ œ

JSX

import {
  Wrapper,
  Title,
  Wrapper_input,
  Wrapper_info,
  Name,
  Input,
  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,
  RegisterBtn,
  Color,
} from "./css";
import { useState } from "react";
import { useMutation, gql } from "@apollo/client";
const CREATE_BOARD = gql`
  mutation createBoard($writer: String, $title: String, $contents: String) {
    createBoard(writer: $writer, title: $title, contents: $contents) {
      _id
      number
      message
    }
  }
`;
export default function freeBoardFrom() {
  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("");
  function onChangeName(event) {
    setName(event.target.value);
  }
  function onChangePassword(event) {
    setPassword(event.target.value);
  }
  function onChangeSubtitle(event) {
    setSubtitle(event.target.value);
  }
  function onChangeContent(event) {
    setContent(event.target.value);
  }
  const [client] = useMutation(CREATE_BOARD);
  const Signup = async () => {
    //๊ฐ€์ž…ํ•˜๊ธฐ
    if (TheName === "") {
      //์ด๋ฆ„์ด ๋นˆ๊ฐ’์ด๋ผ๋ฉด
      setNameError("์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    } else {
      setNameError("");
    }
    if (ThePassword === "") {
      setPasswordError("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    } else {
      setPasswordError("");
    }
    if (TheSubtitle === "") {
      setSubtitleError("์ œ๋ชฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    } else {
      setSubtitleError("");
    }
    if (TheContent === "") {
      setContentError("๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”");
    } else {
      setContentError("");
    }
    if (
      TheName !== "" &&
      ThePassword !== "" &&
      TheSubtitle !== "" &&
      TheContent !== ""
    ) {
      alert("๊ฒŒ์‹œ๊ธ€์ด ๋“ฑ๋ก๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
      const result = await client({
        variables: {
          //variables๊ฐ€ $์—ญํ• ์„ ํ•œ๋‹ค.
          writer: TheName,
          title: TheSubtitle,
          contents: TheContent,
        },
      });
      console.log(result);
    }
  };
  return (
    <Wrapper>
      <Title>๊ฒŒ์‹œ๋ฌผ๋“ฑ๋ก</Title>
      <Wrapper_input>
        <Wrapper_info>
          <Name>์ž‘์„ฑ์ž</Name>
          <Input
            type="text"
            placeholder="์ด๋ฆ„์„ ์ ์–ด์ฃผ์„ธ์š”"
            onChange={onChangeName}
          />
          <Color>{NameError}</Color>
        </Wrapper_info>
        <Wrapper_info>
          <Password>๋น„๋ฐ€๋ฒˆํ˜ธ</Password>
          <Input
            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>
        <RegisterBtn onClick={Signup}>๋“ฑ๋กํ•˜๊ธฐ</RegisterBtn>
      </Wrapper_register>
    </Wrapper>
  );
}

Image


๐Ÿฅš MEMO

  1. ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฐ˜๋“œ์‹œ ์•ˆ์ชฝ์— ๋„ฃ์–ด์ค˜์•ผ ํ•œ๋‹ค.!
  2. ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์— ๋”ฐ๋ผ var์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.
    const๋กœ ๋งŒ๋“ค์—ˆ์ง€๋งŒ var๋กœ ๋ฐ”๊ฟ”์ค„ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.
    ๊ทธ๋ž˜์„œ ์˜›๋‚  ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•ด์คŒ!
  3. ํšจ์œจ์ ์ธ ์ฒ˜๋ฆฌ๋Š” ๋น„๋™๊ธฐ๋กœ ํ•˜๊ณ 
    ์–ด์ฉ” ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„๋งŒ ๋™๊ธฐ๋กœ ํ•œ๋‹ค.
  4. ์—ญ์Šฌ๋ž˜์‹œ() ์ค„๋ฐ”๊ฟˆ
  5. apollo๋กœ ์„ธํŒ…, ์ปดํฌ๋„ŒํŠธ๋Š” ์ ‘์†
  6. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ๋“ค (axios๋“ฑ) ๋Œ€๋ถ€๋ถ„์€ ๋น„๋™๊ธฐ๋กœ ์ž‘๋™์„ ํ•œ๋‹ค.
  7. async / await ๋น„๋™๊ธฐ๋ฅผ ๋™๊ธฐ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ๋ช…๋ น์–ด
  8. npmjs.com ๋‚จ์ด ๋งŒ๋“ค์–ด๋†“์€ ๊ธฐ๋Šฅ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅ
  9. ๋ชจ๋“ ํŽ˜์ด์ง€์—์„œ graph-ql์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ณ ์‹ถ์„ ๋•Œ ์„ค์ •ํ•˜๋Š” ๋ฒ•
    app.js ->๋ชจ๋“ ํŽ˜์ด์ง€ ๊ณตํ†ต ์„ค์ •ํŒŒ์ผ
  10. ์˜ค๋ฅ˜๋ฐœ์ƒ ์‹œ ๋ฐ˜๋“œ์‹œ ํ•ด๋‹น ๋ฌธ๊ตฌ ์ฝ์–ด์„œ ํ˜ผ์ž ํ•ด๊ฒฐํ•ด๋ณด๋ ค๊ณ  ๋…ธ๋ ฅํ•  ๊ฒƒ!

๐Ÿฅš Q&A

Q.package.json์—์„œ ์„ค์น˜๋œ apollo ํ”„๋กœ๊ทธ๋žจ๋งŒ ์‚ญ์ œ๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”์ง€?
A. ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†์ง€๋งŒ ๋‹ค์Œ ๋ฒˆ์— ๋˜ ๊ทธ๋Ÿฐ๋‹ค๋ฉด apollo๋งŒ ์ „์ฒด์ ์œผ๋กœ ๊น” ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์žˆ๋‹ค๊ณ  ํ•˜์…”์„œ ๋ฉ˜ํ† ๋‹˜๊ป˜์„œ ์•Œ๋ ค๋‹ฌ๋ผ๊ณ  ํ•˜์…จ๋‹ค.

๐Ÿฅš ์˜ค๋Š˜์˜ ํšŒ๊ณ 

์ง„์งœ ๋งŽ์€ ์–‘์„ ๋ฐฐ์šด ๊ฒƒ ๊ฐ™์€ ์˜ค๋Š˜์˜ ์ˆ˜์—…์ด์—ˆ๋‹ค.
API๊ฐ€ ๋‘ ์ข…๋ฅ˜๋กœ ๋‚˜๋‰˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ๋„ ์ฒ˜์Œ ์•Œ์•˜๊ณ ,
์‹ค์ œ๋กœ ์ ์šฉํ•ด๋ณด๋ฉฐ ๊ฐ๊ฐ์˜ ์ฐจ์ด์ ์— ๋Œ€ํ•ด ์•Œ ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์ด์—ˆ๋‹ค.
๋™๊ธฐ์™€ ๋น„๋™๊ธฐ, ๊ทธ๋ฆฌ๊ณ  promise์— ๊ด€๋ จํ•œ ๋‚ด์šฉ์„
์ง€๋‚œ ์˜จ๋ผ์ธ ํ”„๋ฆฌ์บ ํ”„ ๋•Œ ์ง„ํ–‰ํ–ˆ๋˜ ์ ์ด ์žˆ์–ด์„œ
๋…ธ์…˜์— ์—ด์‹ฌํžˆ ์ •๋ฆฌํ•ด ๋†“์•˜๋Š”๋ฐ, ํ•จ๊ป˜ ๋ณด๋‹ˆ ๋„์›€์ด ์ž˜ ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค!
์ด๋ž˜์„œ ์˜ค๋Š˜ ๋ฐฐ์šด ๊ฒƒ์€ ์˜ค๋Š˜ ์ •๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ,,
์—ด์‹ฌํžˆ ๊ณผ์ œ๋ฅผ ํ•˜๋˜ ์ค‘์— package.json์—์„œ ์„ค์น˜๋œ apollo๊ฐ€ ์‚ญ์ œ๊ฐ€ ๋˜์–ด ์ž๊พธ๋งŒ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.
์„ค์น˜๋œ ํ”„๋กœ๊ทธ๋žจ์ด ์‚ญ์ œ๊ฐ€ ๋˜์—ˆ์„ ๊ฒƒ์ด๋ผ๊ณค ์ƒ๊ฐ๋„ ๋ชปํ–ˆ๋Š”๋ฐ,
package.json์— ํ˜น์‹œ๋‚˜ ๊ฐ€๋ดค๋”๋‹ˆ apolloํ”„๋กœ๊ทธ๋žจ๋งŒ ๊น”๋ ค์žˆ์ง€ ์•Š์•˜๋”ฐ,,
๋ถ„๋ช… ๊ฑด๋“  ์ ์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ,,ใ… ใ… 
์žฌ์„ค์น˜ ํ›„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋˜‘๊ฐ™์•˜๋‹ค
๊ฒฐ๊ตญ ์ฐฝ์„ ๋‹ค ๋„๊ณ  ์—ด์–ด์„œ ๋‹ค๋ฅธ ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ด ๋„ฃ์–ด์„œ ํ•˜๋‹ˆ ํ•ด๊ฒฐ์ด ๋˜์—ˆ๋‹ค,,
์ด๊ฑธ๋กœ ์‹œ๊ฐ„์„ ๊ฝค๋‚˜ ์žก์•„ ๋จน์–ด๋ฒ„๋ ค์ฏคใ…‹
๊ทธ๋ž˜๋„ ํŽ˜์–ด๋ถ„๋“ค๊ป˜์„œ ์™œ๊ทธ๋Ÿฐ๊ฑด์ง€ ์˜†์—์„œ ๊ฐ™์ด ๊ณ ๋ฏผํ•ด์ฃผ์‹œ๊ณ  ๋„์™€์ฃผ์‹œ๋Š” ๋ฐ”๋žŒ์—
๊ธˆ๋ฐฉ ํ•ด๊ฒฐํ•œ ๊ฒƒ ๊ฐ™๋‹ค! ๊ฐ์‚ฌํ•œ ๋งˆ์Œ๐Ÿ™
์ง€๋‚œ 3์ผ์ฐจ๋ณด๋‹ค๋Š” ์˜ค๋Š˜์ด ์ง‘์ค‘์ด ์ข€ ์ž˜ ๋˜์–ด์„œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฑด ๊ธˆ๋ฐฉ ํ–ˆ์ง€๋งŒ,
์ดˆ๋ฐ˜์— HTML๊ณผ CSS๋ฅผ ์งœ๋Š”๋ฐ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ ธ๋‹ค,,
๋นจ๋ฆฌ ํ•ด๋ฒ„๋ฆฌ๊ณ  ๊ธฐ๋Šฅํ•˜๊ณ  ์‹ถ์€๋Ž… ใ… ใ… ,,,
๊ฐˆ์ˆ˜๋ก ๋‚˜๋Š” ๊พธ๋ฏธ๋Š” ๊ฒƒ๋ณด๋‹ค ์›€์ง์ด๊ฒŒ๋” ๋งŒ๋“œ๋Š” ๊ฑธ ๋” ์ข‹์•„ํ•œ๋‹ค๋Š” ๊ฒŒ ๋Š๊ปด์ง„๋‹ค,,ใ…‹ใ…‹
ํ•˜์ง€๋งŒ ๋‚˜๋Š” 1px ํ•˜๋‚˜ํ•˜๋‚˜ ์‹ ๊ฒฝ์“ฐ๋Š” ํ”„๋ก ํŠธ์ธ๊ฑธ?!
๊ฒฐ๊ตญ์—” ์™„์„ฑ๋œ ๋ชจ์Šต์„ ๋ณด๊ณ ์•ผ ๋งˆ๋Š” ๋‚˜
๋‚ด์ผ์ด๋ฉด ๋ฒŒ์จ ํ•œ์ฃผ์˜ ๋งˆ์ง€๋ง‰ ๋‚ ์ด๋‹ค,,
ํ•˜๋ฃจ๊ฐ€ ์•„์ฃผ ๊ธฐ์ผ~~~๊ฒŒ ๋Š๊ปด์กŒ ํ•˜๋ฃจํ•˜๋ฃจ์˜€์ง€๋งŒ
์ž˜ ์ง€๋‚˜์˜จ ๋‚ด๊ฐ€ ์ž๋ž‘์Šค๋Ÿฝ๋‹ค peace -

profile
JUST DO WHATEVER

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