๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Frontend Dev/๐Ÿฅ ์ฝ”๋“œ์Šคํ…Œ์ด์ธ  FE ๋ถ€ํŠธ์บ ํ”„

Section3 Unit1 [์ž๋ฃŒ๊ตฌ์กฐ/์•Œ๊ณ ๋ฆฌ์ฆ˜] ์žฌ๊ท€ - ๊ณผ์ œ JSON.stringify, Tree UI

๋ฐ˜์‘ํ˜•


Section3 Unit1 [์ž๋ฃŒ๊ตฌ์กฐ/์•Œ๊ณ ๋ฆฌ์ฆ˜] ์žฌ๊ท€ - ๊ณผ์ œ JSON.stringify, Tree UI

 

โญ๏ธ ๊ณผ์ œ 1. JSON.stringify

โœ๏ธ ์ด๋ฒˆ ๊ณผ์ œ๋Š” ์žฌ๊ท€๋ฅผ ์ด์šฉํ•ด ๋ฉ”์„œ๋“œ JSON.stringify๋ฅผ ํ•จ์ˆ˜์˜ ํ˜•ํƒœ๋กœ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ œ์˜€๋‹ค.

 

์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๊ฒƒ์— ์–ด๋ ค์›€์„ ๋Š๊ปด์„œ ๊ทธ๋Ÿฐ์ง€ ์ด๋ฒˆ ๊ณผ์ œ๋Š” ์‰ฝ์ง€ ์•Š์•˜๋‹ค.

ํ…Œ์ŠคํŠธ์— ๊ทธ๋ƒฅ ํ†ตํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด const stringifyJSON = JSON.stringify; ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค. (๋„ˆ๋ฌด๋‚˜ ์†์‰ฝ๊ฒŒ ํ•ด๊ฒฐ~)

ํ•˜์ง€๋งŒ ์ด ๊ณผ์ œ๋Š” ์žฌ๊ท€๋ฅผ ๊ณต๋ถ€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ˆ, ํ•˜๋‚˜์”ฉ ๊ตฌํ˜„ํ•ด๋ณด์ž.

 

โœจ ๊ตฌํ˜„๊ณผ์ • & ์ฝ”๋“œ

 1. ์ฒ˜์Œ์—๋Š” ๊ฐ์ด ์žกํžˆ์ง€ ์•Š์•„์„œ ํ•œ์ฐธ์„ ํ—ค๋งค๊ณ , ์‹œ์ž‘์„ ๋ชปํ•˜๊ณ  ์žˆ์—ˆ๋‹ค... ๐Ÿ˜ญ

 2. ๋ฐฐ์—ด๊ณผ ๊ฐ์ฒด๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š”, ๋‹จ์ˆœํžˆ "" ์ด๋ ‡๊ฒŒ ๋”ฐ์˜ดํ‘œ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์„ ์•Œ์•„์ฐจ๋ฆฌ๊ณ ๋Š” ์กฐ๊ฑด๋ฌธ์œผ๋กœ number, string, boolean, null ์ผ ๊ฒฝ์šฐ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์—ˆ๋‹ค.

 3. ํ•จ์ˆ˜์™€ undefined์ธ ๊ฒฝ์šฐ๋Š” stringify ๋˜์ง€ ์•Š๋Š”๋‹ค. 

 4. ๋ฐฐ์—ด๊ณผ ๊ฐ์ฒด๋ฅผ ๋ณ€ํ™˜์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋‚‘๋‚‘๊ฑฐ๋ฆฌ๋‹ค ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์ž‘์„ฑ์„ ์™„๋ฃŒํ•˜์˜€๋‹ค. (๊ทธ๋ž˜๋„ ์ ‘๊ทผ์€ ๋น„์Šทํ•˜๊ฒŒ ํ•˜๊ณ  ์žˆ์—ˆ์–ด...๐Ÿฅฒ)

 

function stringifyJSON(obj) {

  // Number ๋˜๋Š” Boolean์ผ ๊ฒฝ์šฐ
  if (typeof obj === "number" || typeof obj === "boolean" || obj === null) {
    return `${obj}`
  }

  // String์ผ ๊ฒฝ์šฐ
  if (typeof obj === "string") {
    return `"${obj}"`
  }

  // Array์ผ ๊ฒฝ์šฐ
  if (Array.isArray(obj)) {
    const result = [];

    // Reference ์—์„œ๋Š” forEach๋กœ ์ž‘์„ฑ
    for (let el of obj) {
      result.push(stringifyJSON(el))
    }
    return `[${result}]`
  }

  // Object์ผ ๊ฒฝ์šฐ
  if (typeof obj === "object") {
    let result = "";

    for (let key in obj) {
      // console.log(el, obj[el])
      let objKey = stringifyJSON(key);
      let objValue = stringifyJSON(obj[key])

      // ํ•จ์ˆ˜์™€ undefined๋Š” stringify๋˜์ง€ ์•Š๋Š”๋‹ค.
      if (typeof objValue === "function" || objValue === undefined) {
        continue;
      } else {
        result += `${objKey}:${objValue},`
      }
    }
    return `{${result.slice(0, result.length - 1)}}`
  }
};

 

โญ๏ธ ๊ณผ์ œ 2. Tree UI

โœ๏ธ Tree UI ๊ณผ์ œ๋Š” ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•  ๋•Œ ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณผ์ œ์ด๋‹ค.

 

Tree UI๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•  ์ƒ๊ฐ์€ ํ•ด๋ณธ ์ ์ด ์—†์ง€๋งŒ(์žฌ๊ท€ํ•จ์ˆ˜ ์‚ฌ์šฉ์„ ์ž˜ ๋ชปํ•˜๋‹ˆ..), Tree UI๋ฅผ ์žฌ๊ท€๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‹ ๊ธฐํ•˜๊ณ  ์žฌ๋ฐŒ๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋œ ๊ณผ์ œ์˜€๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ์œ„ ๊ณผ์ œ๋ณด๋‹ค ์žฌ๋ฐŒ์—ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฌผ์ด ๋‚˜์˜ค๋ฉด ๋˜๊ณ , menu ๋ฐฐ์—ด๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. 

const menu = [
  {
    type: 'group',
    name: '์Œ๋ฃŒ',
    children: [
      {
        type: 'group',
        name: '์ฝœ๋“œ ๋ธŒ๋ฃจ',
        children: [
          { type: 'item', name: '๋‚˜์ดํŠธ๋กœ ์ฝœ๋“œ ๋ธŒ๋ฃจ' },
          { type: 'item', name: '๋Œ์ฒด ์ฝœ๋“œ ๋ธŒ๋ฃจ' },
          { type: 'item', name: '์ œ์ฃผ ๋น„์ž๋ฆผ ์ฝœ๋“œ ๋ธŒ๋ฃจ' },
          { type: 'item', name: '์ฝœ๋“œ ๋ธŒ๋ฃจ' },
        ],
      },
      {
        type: 'group',
        name: 'ํ”„๋ผํ‘ธ์น˜๋…ธ',
        children: [
          { type: 'item', name: '์• ํ”Œ ์ฟ ํ‚ค ํฌ๋ฆผ ํ”„๋ผํ‘ธ์น˜๋…ธ' },
          { type: 'item', name: '๋”๋ธ” ์—์Šคํ”„๋ ˆ์†Œ ์นฉ ํ”„๋ผํ‘ธ์น˜๋…ธ' },
          { type: 'item', name: '๋ชจ์นด ํ”„๋ผํ‘ธ์น˜๋…ธ' },
          { type: 'item', name: 'ํ”ผ์Šคํƒ€์น˜์˜ค ํฌ๋ฆผ ํ”„๋ผํ‘ธ์น˜๋…ธ' },
        ],
      },
      { ... } // ์œ„์™€ ๊ฐ™์€ children์ด ์—ฌ๋Ÿฌ ๊ฐœ ๋” ์žˆ๋Š” ๊ตฌ์กฐ
     ]
   }
   // ์œ„์™€ ๊ฐ™์€ group์ด ์—ฌ๋Ÿฌ ๊ฐœ ๋” ์žˆ๋Š” ๊ตฌ์กฐ
 ]

 

โœจ ๊ตฌํ˜„๊ณผ์ • & ์ฝ”๋“œ

 ๊ตฌํ˜„๊ณผ์ •์€ ์ฃผ์„์œผ๋กœ ์ •๋ฆฌํ•ด๋‘์—ˆ๋‹ค.

 ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋ช…๋ นํ˜•(imperitive) ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€๊ณ , ๋ ˆํผ๋Ÿฐ์Šค ์ฝ”๋“œ๋ฅผ ๋ณด๋‹ˆ ์„ ์–ธํ˜• ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋„ ์žˆ์—ˆ๋‹ค! ์„ ์–ธํ˜• ์ฝ”๋“œ๋ณด๋‹ค๋Š” ๋ช…๋ นํ˜•์œผ๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๊ฐ€ ๋‚˜๋Š” ๋ณด๊ธฐ์— ๋” ํŽธํ–ˆ๋‹ค.

 

function createTreeView(menu, currentNode) {
  
  // menu์˜ ๊ฐ์ฒด ๊ฒ€์‚ฌ
  menu.map((el) => {
    console.log(el)
    /*
      {type: 'group', name: '์Œ๋ฃŒ', children: Array(5)}
      {type: 'group', name: '์Œ์‹', children: Array(6)}
      {type: 'group', name: '๊ตฟ์ฆˆ', children: Array(3)}
      {type: 'group', name: '์นด๋“œ', children: Array(4)}
    */

    /** result ํ˜•ํƒœ : ul#root > li > input, span, ul > li > input, span, ul > li ...
     * ul#root ๋Š” ์ด๋ฏธ ์ƒ์„ฑ๋˜์–ด ์žˆ์Œ
     * li ์ƒ์„ฑ
     */
    const li = document.createElement("li");
    
    /** ๊ฐ์ฒด ์•ˆ์— children์ด ์žˆ์„ ๊ฒฝ์šฐ input, span, ul ์ƒ์„ฑ
     * input type="checkbox" 
     * span textContent : name (ex.์Œ๋ฃŒ)
     */
    // ์•„๋ž˜ if ๋ฌธ์ด ๋ฐ˜๋ณต๋˜์–ด์•ผ ํ•จ. (children์ด ์—†์„ ๋•Œ๊นŒ์ง€)
    if (el.hasOwnProperty("children")) {
      const input = document.createElement("input");
      const span = document.createElement("span");
      const ul = document.createElement("ul");

      input.setAttribute("type", "checkbox");
      // input.type = "checkbox"
      span.textContent = el.name;

      li.append(input, span, ul);
      
      currentNode.append(li);
      /* ์ตœ์ดˆ ๋ Œ๋”๋ง
        <ul id="root">
          <li>
            <input type="checkbox" />
            <span>${el.name}</span>
            <ul></ul>
          </li>
        </ul>
      */

      // ์žฌ๊ท€ํ•จ์ˆ˜ ํ˜ธ์ถœ
      // createTreeView(menu, currentNode)
      // menu๋Š” ์ถ”๊ฐ€ํ•  ๊ฒƒ, currentNode๋Š” ์ถ”๊ฐ€ํ•  ๊ณณ 
      createTreeView(el.children, ul);
      
    } else {
      // console.log(`${el.name}์—๋Š” ๋”์ด์ƒ children ์—†์Œ`);

      // ๊ฐ์ฒด ์•ˆ์— children์ด ์—†๋Š” ๊ฒฝ์šฐ li๋งŒ append
      currentNode.append(li);
      li.textContent = el.name;
    }
  })
}

 


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

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

 ์ •๊ทœ ์ˆ˜์—… ํ›„์— ์Šคํ„ฐ๋””๋‹ญ ์ด๋ฒคํŠธ(?)์˜ ๋งˆ์ง€๋ง‰ ์Šคํ„ฐ๋””๋กœ “๋‚˜๋งŒ์˜ ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ ๋งŒ๋“ค๊ธฐ”๊ฐ€ ์ง„ํ–‰๋˜์—ˆ๋Š”๋ฐ, ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ฒ˜์Œ ๊ตฌ์ถ•ํ•˜๋ฉฐ ์•Œ์•„์•ผ ํ•  ๋‚ด์šฉ๋“ค์— ๋Œ€ํ•œ ์ˆ˜์—…์ด ์ง„ํ–‰๋˜์–ด์„œ ๊ฝค ์œ ์ตํ•˜๊ณ , ์žฌ๋ฏธ์žˆ์—ˆ๋‹ค. npm์œผ๋กœ ๋ฐฐํฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ๋„ ๋„ˆ๋ฌด ์‹ ๊ธฐํ•˜๊ณ  ์‹ ์„ ํ–ˆ๋‹ค. ๋‚ด๊ฐ€ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์ผ์ข…์˜ ํ…œํ”Œ๋ฆฟ์„ ๋ฐฐํฌํ•ด์„œ, npm์œผ๋กœ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋‹ˆ?! ๋„ˆ๋ฌด ์žฌ๋ฐŒ์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. ์ˆ˜์—…์„ ๋“ฃ๋‹ค๊ฐ€ ๊ถ๊ธˆํ•œ ์ ์ด ๋” ์ƒ๊ฒผ๋Š”๋ฐ, ๊ทธ๊ฒƒ๋„ ์ข€ ๋” ์ฐพ์•„๋ณด๋ฉฐ ๊ณต๋ถ€ํ•ด์•ผ ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. ๊ถ๊ธˆํ•œ ๊ฒŒ ์ƒ๊ธด๋‹ค๋Š” ๊ฑด ์ฆ๊ฑฐ์šด ์ผ์ด๋‹ค.

 ์ตœ๊ทผ๋“ค์–ด ๊ฑฐ์˜ ์‰ฌ๋Š”๋‚  ์—†์ด ๊ณต๋ถ€๋ฅผ ํ•˜๋‹ค๋ณด๋‹ˆ ํ”ผ๋กœ๊ฐ€ ํ™• ์Œ“์—ฌ๊ฐ์ด ๋ชธ์œผ๋กœ ๋Š๊ปด์ง„๋‹ค. ํšŒ๋ณต์˜ ํœด์‹์ด๋“ , ๋ง‘์€ ๋ฆฌํ”„๋ ˆ์‹œ๋“  ๋ญ”๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™๋‹ค… ๊ทธ๋Ÿฌ๋‹ˆ ์˜ค๋Š˜์€ ์—ด๋‘์‹œ ์ „์— ์ž ์ž๋ฆฌ์— ๋“ค์–ด์•ผ๊ฒ ๋‹ค.

 ๋‚ด์ผ์€ ์ข€ ๋” ํšจ์œจ์ ์ด๊ณ , ์—ด์‹ฌํžˆ ๊ณต๋ถ€ํ•ด์•ผ์ง€.

๋ฐ˜์‘ํ˜•