Week 1

๐Ÿ“Š ๋Œ€ํ™” ๋ถ„์„: ์‚ฌ์šฉ์ž๋‹˜์˜ ์งˆ๋ฌธ ํŒจํ„ด

์งˆ๋ฌธ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋ถ„๋ฅ˜

์นดํ…Œ๊ณ ๋ฆฌ ์งˆ๋ฌธ ๋‚ด์šฉ ๋นˆ๋„
JavaScript ๊ธฐ๋ณธ Array methods (map, filter, sort), localeCompare ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด
Svelte ๊ฐœ๋… Reactive statement ($:), ์–ธ์ œ ์‚ฌ์šฉ? ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด
๋ฐ์ดํ„ฐ ํ๋ฆ„ MQTT ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ, ์ •๋ ฌ ํƒ€์ด๋ฐ ๐Ÿ”ด๐Ÿ”ด
๋ธŒ๋ผ์šฐ์ € API history.replaceState, localStorage ๐Ÿ”ด๐Ÿ”ด
์•„ํ‚คํ…์ฒ˜ App.svelte ๋™์ž‘, routes ๋ฐฐ์—ด ์ˆœ์„œ ๐Ÿ”ด
๋””๋ฒ„๊น… โ€œ์™œ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ?โ€, Edge case ๐Ÿ”ด

๐ŸŽฏ ์•ฝ์  ๋ถ„์„

  1. JavaScript ๋ฐฐ์—ด/๊ฐ์ฒด ๋ฉ”์„œ๋“œ ์ดํ•ด ๋ถ€์กฑ ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€œalertData์—์„œ ์ƒˆ ๋ฐฐ์—ด ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•?โ€
  • โ€œlocaleCompare๊ฐ€ ๋ญ์•ผ?โ€
  • โ€œparseInt() vs localeCompare ์ฐจ์ด?โ€
  • โ€œ์ •๋ ฌ ์ฃผ์„์ฒ˜๋ฆฌํ•ด๋„ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™๋”๋ผโ€

๋ฌธ์ œ:

  • Array.map(), filter(), reduce() ๋™์ž‘ ์›๋ฆฌ ๋ถˆ๋ช…ํ™•
  • Set์˜ ์ˆœ์„œ ๋ณด์žฅ ๊ฐœ๋… ๋ชจ๋ฆ„
  • ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ดํ•ด ๋ถ€์กฑ

  1. Svelte Reactive Statement ๊ฐœ๋… ํ˜ผ๋ž€ ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€$: ์—†์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์„๊นŒ?โ€
  • โ€œ์‹œ๋‹ˆ์–ด๋Š” $:๋ฅผ ์‹ซ์–ดํ•˜๋Š” ๊ฒƒ ๊ฐ™์•„โ€
  • โ€œMQTT ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ์ž๋™์œผ๋กœ ์ •๋ ฌ ์•ˆ ๋˜์ง€?โ€

๋ฌธ์ œ:

  • $:์˜ ๋™์ž‘ ์‹œ์  ๋ถˆ๋ช…ํ™•
  • ์–ธ์ œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ํŒ๋‹จ ๋ชป ํ•จ
  • Reactive vs Imperative ์ฐจ์ด ์ดํ•ด ๋ถ€์กฑ

  1. ๋ฐ์ดํ„ฐ ํ๋ฆ„๊ณผ ํƒ€์ด๋ฐ ์ดํ•ด ๋ถ€์กฑ ๐Ÿ”ด๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€œ์ตœ์ดˆ ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ alertData๊ฐ€ ์ž๋™์œผ๋กœ ์ •๋ ฌ ์•ˆ ๋˜์ง€?โ€
  • โ€œMQTT๋กœ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜?โ€

๋ฌธ์ œ:

  • ์ดˆ๊ธฐ ์‹คํ–‰ vs ๋Ÿฐํƒ€์ž„ ์—…๋ฐ์ดํŠธ ์ฐจ์ด ๋ชจ๋ฆ„
  • ๋ถˆ๋ณ€์„ฑ(Immutability) ๊ฐœ๋… ๋ถ€์กฑ

  1. App.svelte ๊ฐ™์€ โ€œํฐ ๊ทธ๋ฆผโ€ ์ดํ•ด ๋ถ€์กฑ ๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€œApp.svelte๊ฐ€ ํ•˜๋Š” ์ผ์ด ์ดํ•ด๊ฐ€ ์•ˆ ๊ฐ€โ€
  • โ€œroutes[2]๋Š” ์—†๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€?โ€

๋ฌธ์ œ:

  • ์ปดํฌ๋„ŒํŠธ ์ƒ๋ช…์ฃผ๊ธฐ ์ดํ•ด ๋ถ€์กฑ
  • ๋ฐฐ์—ด ์ธ๋ฑ์‹ฑ ๊ธฐ๋ณธ ๊ฐœ๋… ๋ถ€์กฑ

๐Ÿ’ช ๊ฐ•์  ๋ถ„์„

โœ… ์ž˜ํ•˜๋Š” ๊ฒƒ๋“ค

  1. ์งˆ๋ฌธ์„ ์ž˜ ํ•จ: ์ดํ•ด ์•ˆ ๋˜๋ฉด ๋ฐ”๋กœ ๋ฌผ์–ด๋ด„
  2. ์ง์ ‘ ํ…Œ์ŠคํŠธ: ์ฝ”๋“œ ์ˆ˜์ •ํ•˜๊ณ  ์ฝ˜์†” ์ฐ์–ด๋ด„
  3. Step-by-step ์‚ฌ๊ณ : โ€œํ•œ ์ค„์”ฉ ๋˜์งš์–ด ๊ฐ€๋ฉด์„œ ๋™์ž‘ ์ ๊ฒ€โ€
  4. ํ”ผ๋“œ๋ฐฑ ์ˆ˜์šฉ: ์‹œ๋‹ˆ์–ด ์กฐ์–ธ ์ ๊ทน ๋ฐ˜์˜

๐Ÿ“š ๋งž์ถคํ˜• ํ•™์Šต ์ปค๋ฆฌํ˜๋Ÿผ

๐ŸŽ“ Phase 1: JavaScript ๊ธฐ์ดˆ ๋‹ค์ง€๊ธฐ (1-2์ฃผ)

Week 1: ๋ฐฐ์—ด ์™„๋ฒฝ ์ •๋ณต

Day 1-2: ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ ๊ธฐ๋ณธ

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 1: alertData์—์„œ ์ธต ๋ชฉ๋ก ์ถ”์ถœ (์ค‘๋ณต ์ œ๊ฑฐ) const alertData = [ { floorName: โ€˜1Fโ€™, status: โ€˜Alertโ€™ }, { floorName: โ€˜2Fโ€™, status: โ€˜Closedโ€™ }, { floorName: โ€˜1Fโ€™, status: โ€˜Offlineโ€™ }, ];

// TODO: Set ์‚ฌ์šฉํ•ด์„œ [โ€˜1Fโ€™, โ€˜2Fโ€™] ๋งŒ๋“ค๊ธฐ const floors = [โ€ฆnew Set(alertData.map(a => a.floorName))]; console.log(floors);

// ๊ณผ์ œ 2: Status๋ณ„ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ // ๊ฒฐ๊ณผ: { Alert: 1, Closed: 1, Offline: 1 } const statusCount = alertData.reduce((acc, item) => { acc[item.status] = (acc[item.status] || 0) + 1; return acc; }, {});

 ๋ฐฉ๋ฒ• 1: ์ด์ค‘ reduce ์‚ฌ์šฉ (๊ณ ๊ธ‰)

  ๊ฐ ๊ฑด๋ฌผ์˜ ์ธต ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ alertCount๋ฅผ ๋ˆ„์ :

  function calculateTotalAlerts() {
    const total = MOCK_CENTER_ALARM_STAT.reduce((sum, buildingObj) => {
      // 1. ๊ฑด๋ฌผ ๊ฐ์ฒด์—์„œ ๊ฑด๋ฌผ๋ช… ํ‚ค ์ฐพ๊ธฐ (A๋™, B๋™)
      const buildingKey = Object.keys(buildingObj).find(key => key !== 'total');
      const floors = buildingObj[buildingKey]; // ์ธต ๋ฐฐ์—ด

      // 2. ๊ฐ ์ธต์˜ alertCount ํ•ฉ์‚ฐ
      const buildingTotal = floors.reduce((floorSum, floor) => {
        return floorSum + floor.alertCount;
      }, 0);

      return sum + buildingTotal;
    }, 0);

    return total;
  }

  ๋””๋ฒ„๊น…์šฉ console.log ์ถ”๊ฐ€ ๋ฒ„์ „:
  function calculateTotalAlerts() {
    const total = MOCK_CENTER_ALARM_STAT.reduce((sum, buildingObj) => {
      const buildingKey = Object.keys(buildingObj).find(key => key !== 'total');
      const floors = buildingObj[buildingKey];

      console.log('๊ฑด๋ฌผ:', buildingKey, '์ธต ๊ฐœ์ˆ˜:', floors.length);

      const buildingTotal = floors.reduce((floorSum, floor) => {
        console.log('  ์ธต:', floor.floorName, 'alertCount:', floor.alertCount);
        return floorSum + floor.alertCount;
      }, 0);

      console.log('๊ฑด๋ฌผ ํ•ฉ๊ณ„:', buildingTotal);
      return sum + buildingTotal;
    }, 0);

    console.log('๐Ÿ”ฅ ์ตœ์ข… ์ „์ฒด ํ•ฉ๊ณ„:', total);
    return total;
  }

  ---
  ๋ฐฉ๋ฒ• 2: forEach ์ค‘์ฒฉ (์ดˆ๋ณด์ž ์นœํ™”์ )

  reduce๊ฐ€ ์–ด๋ ต๋‹ค๋ฉด forEach๋กœ ๋จผ์ € ์—ฐ์Šต:

  function calculateTotalAlerts() {
    let total = 0;

    MOCK_CENTER_ALARM_STAT.forEach(buildingObj => {
      // ๊ฑด๋ฌผ ํ‚ค ์ฐพ๊ธฐ
      const buildingKey = Object.keys(buildingObj).find(key => key !== 'total');
      const floors = buildingObj[buildingKey];

      // ๊ฐ ์ธต์˜ alertCount ๋”ํ•˜๊ธฐ
      floors.forEach(floor => {
        console.log('์ถ”๊ฐ€:', floor.floorName, floor.alertCount);
        total += floor.alertCount;
      });
    });

    console.log('์ตœ์ข… ํ•ฉ๊ณ„:', total);
    return total;
  }

  ---
  ๋ฐฉ๋ฒ• 3: flatMap ์‚ฌ์šฉ (๋ชจ๋˜ JavaScript)

  ๊ฐ€์žฅ ๊น”๋”ํ•œ ๋ฐฉ๋ฒ•:

  function calculateTotalAlerts() {
    const total = MOCK_CENTER_ALARM_STAT
      .flatMap(buildingObj => {
        const buildingKey = Object.keys(buildingObj).find(key => key !== 'total');
        return buildingObj[buildingKey]; // ๋ชจ๋“  ์ธต์„ ํ•˜๋‚˜์˜ ๋ฐฐ์—ด๋กœ ํ‰ํƒ„ํ™”
      })
      .reduce((sum, floor) => sum + floor.alertCount, 0);

    return total;
  }

  ---
  ๐ŸŽฏ ํ•™์Šต ํฌ์ธํŠธ

  Object.keys() ์ดํ•ดํ•˜๊ธฐ

  const obj = { A๋™: [...], total: 9 };
  Object.keys(obj); // ['A๋™', 'total']

  find()๋กœ ์กฐ๊ฑด ํ•„ํ„ฐ๋ง

  const keys = ['A๋™', 'total'];
  const buildingKey = keys.find(key => key !== 'total'); // 'A๋™'

  ์ด์ค‘ reduce์˜ ํ๋ฆ„

  ์™ธ๋ถ€ reduce: ๊ฑด๋ฌผ๋ณ„ ์ˆœํšŒ (A๋™ โ†’ B๋™)
    โ†“
    ๋‚ด๋ถ€ reduce: ์ธต๋ณ„ ์ˆœํšŒ (1F โ†’ 2F โ†’ 3F โ†’ 4F)
      โ†“
      alertCount ๋ˆ„์ 

  ---
  ๐Ÿ’ก ์ถ”์ฒœ ํ•™์Šต ์ˆœ์„œ

  1. ๋จผ์ € ๋ฐฉ๋ฒ• 2 (forEach)๋กœ ์‹œ์ž‘ โ†’ ๋กœ์ง ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›€
  2. ๋ฐฉ๋ฒ• 1 (์ด์ค‘ reduce)๋กœ ๋„์ „ โ†’ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์—ฐ์Šต
  3. ๋ฐฉ๋ฒ• 3 (flatMap) โ†’ ๊ณ ๊ธ‰ ๊ธฐ๋ฒ• ๋ง›๋ณด๊ธฐ
     
     
     
     
 function getFloorAlertCount(bldgName, floorID) {
   // 1. MOCK_CENTER_ALARM_STAT์—์„œ ๊ฑด๋ฌผ ์ฐพ๊ธฐ
   // 2. ๊ฑด๋ฌผ์˜ ์ธต ๋ฐฐ์—ด์—์„œ floorID ๋งค์นญ
   // 3. alertCount ๋ฐ˜ํ™˜ (์—†์œผ๋ฉด 0)
 }

 ํ…œํ”Œ๋ฆฟ์—์„œ ์‚ฌ์šฉ:
 {#each bldg.floorList || [] as floor}
   <div class="text-center fw-bold text-mute">
     {getFloorAlertCount(bldg.bldgName, floor.floorID)}
   </div>
 {/each}
 

Day 3-4: ์ •๋ ฌ๊ณผ ๋น„๊ต

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 3: ๋‹ค์–‘ํ•œ ์ •๋ ฌ ๋ฐฉ๋ฒ• ๋น„๊ต const floors = [โ€˜10Fโ€™, โ€˜2Fโ€™, โ€˜1Fโ€™, โ€˜B1โ€™, โ€˜Roofโ€™];

// ๋ฐฉ๋ฒ• 1: ๊ธฐ๋ณธ ์ •๋ ฌ (๋ฌธ์ž์—ด) console.log([โ€ฆfloors].sort()); // ๊ฒฐ๊ณผ: [โ€˜1Fโ€™, โ€˜10Fโ€™, โ€˜2Fโ€™, โ€˜B1โ€™, โ€˜Roofโ€™] โ† 10F๊ฐ€ 2F ์•ž์—!

// ๋ฐฉ๋ฒ• 2: localeCompare console.log([โ€ฆfloors].sort((a, b) => a.localeCompare(b))); // ๊ฒฐ๊ณผ: ๊ฐ™์Œ

// ๋ฐฉ๋ฒ• 3: localeCompare + numeric console.log([โ€ฆfloors].sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))); // ๊ฒฐ๊ณผ: [โ€˜1Fโ€™, โ€˜2Fโ€™, โ€˜10Fโ€™, โ€˜B1โ€™, โ€˜Roofโ€™] โ† ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ!

// ๊ณผ์ œ 4: ์™œ ์ด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์ƒ๊ธฐ๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ

Day 5: Set๊ณผ ์ˆœ์„œ

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set
  • ๋ธ”๋กœ๊ทธ: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set#%EC%84%A4%EB%AA%85

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 5: Set์˜ ์ˆœ์„œ ์ดํ•ดํ•˜๊ธฐ const data = [ { time: โ€˜09:00:02โ€™, floor: โ€˜3Fโ€™ }, { time: โ€˜09:00:01โ€™, floor: โ€˜1Fโ€™ }, { time: โ€˜09:00:01โ€™, floor: โ€˜2Fโ€™ }, ];

// Q: Set์€ ์‚ฝ์ž… ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•œ๋‹ค. ๊ฒฐ๊ณผ๋Š”? const floors1 = [โ€ฆnew Set(data.map(a => a.floor))]; console.log(โ€˜์ •๋ ฌ ์ „:โ€™, floors1); // [โ€˜3Fโ€™, โ€˜1Fโ€™, โ€˜2Fโ€™]

// Q: ๋ฐ์ดํ„ฐ๋ฅผ ๋จผ์ € ์ •๋ ฌํ•˜๋ฉด? const sortedData = data.sort((a, b) => a.floor.localeCompare(b.floor, undefined, { numeric: true })); const floors2 = [โ€ฆnew Set(sortedData.map(a => a.floor))]; console.log(โ€˜์ •๋ ฌ ํ›„:โ€™, floors2); // [โ€˜1Fโ€™, โ€˜2Fโ€™, โ€˜3Fโ€™]

// ๊ฒฐ๋ก : Set์€ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜์ง€๋งŒ, ์ž…๋ ฅ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•œ๋‹ค!


Week 2: ๊ฐ์ฒด์™€ ์ฐธ์กฐ

Day 1-2: ์–•์€ ๋ณต์‚ฌ vs ๊นŠ์€ ๋ณต์‚ฌ

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Spread_syntax
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 6: ๋ถˆ๋ณ€์„ฑ ์ดํ•ดํ•˜๊ธฐ let alertData = [ { time: โ€˜09:00:01โ€™, status: โ€˜Alertโ€™ } ];

// โŒ ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ• (์›๋ณธ ๋ณ€๊ฒฝ) alertData.push({ time: โ€˜09:00:02โ€™, status: โ€˜Closedโ€™ });

// โœ… ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ• (์ƒˆ ๋ฐฐ์—ด ์ƒ์„ฑ) alertData = [โ€ฆalertData, { time: โ€˜09:00:02โ€™, status: โ€˜Closedโ€™ }];

// Svelte์—์„œ๋Š” ์™œ ํ›„์ž๋ฅผ ์„ ํ˜ธํ• ๊นŒ? (๋ฐ˜์‘์„ฑ ๋•Œ๋ฌธ!)

Day 3-5: ๋ธŒ๋ผ์šฐ์ € API

  • MDN: https://developer.mozilla.org/ko/docs/Web/API/History_API
  • MDN: https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 7: URL ๋ณ€๊ฒฝ ์—†์ด ์ƒํƒœ ์—…๋ฐ์ดํŠธ // ํ˜„์žฌ URL: http://localhost:5173/floor/1?spaceID=3

// history.replaceState๋กœ ์ฟผ๋ฆฌ์ŠคํŠธ๋ง ์ œ๊ฑฐ const newUrl = window.location.pathname; window.history.replaceState(null, โ€˜โ€™, newUrl); // ๊ฒฐ๊ณผ: http://localhost:5173/floor/1

// ๊ณผ์ œ 8: localStorage ํ™œ์šฉ localStorage.setItem(โ€˜selectedFloorโ€™, โ€˜2Fโ€™); const floor = localStorage.getItem(โ€˜selectedFloorโ€™); console.log(floor); // โ€˜2Fโ€™


๐ŸŽ“ Phase 2: Svelte ํ•ต์‹ฌ ๊ฐœ๋… (1์ฃผ)

Day 1-3: Reactive Statements ์™„์ „ ์ •๋ณต

  • https://svelte.dev/tutorial/reactive-declarations
  • https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 9: $:์˜ ๋™์ž‘ ์‹œ์  ์ดํ•ด let count = 0;

// Q1: ์ด ์ฝ”๋“œ๋Š” ์–ธ์ œ ์‹คํ–‰๋ ๊นŒ? $: doubled = count * 2; $: console.log(โ€˜count changed:โ€™, count);

// Q2: ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋ช‡ ๋ฒˆ ์‹คํ–‰๋ ๊นŒ? function increment() { count += 1; count += 1; count += 1; } // ๋‹ต: console.log๋Š” 1๋ฒˆ๋งŒ ์‹คํ–‰! (Svelte๊ฐ€ batch ์ฒ˜๋ฆฌ)

// ๊ณผ์ œ 10: ์˜์กด์„ฑ ์ดํ•ด let firstName = โ€˜Johnโ€™; let lastName = โ€˜Doeโ€™;

$: fullName = ${firstName} ${lastName}; // Q: firstName๋งŒ ๋ฐ”๋€Œ๋ฉด? โ†’ fullName ์žฌ๊ณ„์‚ฐ // Q: lastName๋งŒ ๋ฐ”๋€Œ๋ฉด? โ†’ fullName ์žฌ๊ณ„์‚ฐ // Q: ๋‘˜ ๋‹ค ์•ˆ ๋ฐ”๋€Œ๋ฉด? โ†’ ์žฌ๊ณ„์‚ฐ ์•ˆ ํ•จ

Day 4-5: ์ƒ๋ช…์ฃผ๊ธฐ

  • https://svelte.dev/tutorial/onmount
  • https://svelte.dev/tutorial/ondestroy

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 11: onMount vs $: ์ฐจ์ด let data = [];

// ๋ฐฉ๋ฒ• 1: onMount onMount(() => { data = fetchData(); // 1๋ฒˆ๋งŒ ์‹คํ–‰ });

// ๋ฐฉ๋ฒ• 2: $: $: { data = fetchData(); // data๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์‹คํ–‰ (๋ฌดํ•œ ๋ฃจํ”„!) }

// Q: ์–ธ์ œ onMount๋ฅผ ์“ฐ๊ณ , ์–ธ์ œ $:๋ฅผ ์“ธ๊นŒ?


๐ŸŽ“ Phase 3: ์‹ค์ „ ํŒจํ„ด (์ง„ํ–‰ ์ค‘)

์ง€๊ธˆ ์ž‘์—…ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋กœ ํ•™์Šต

ํŒจํ„ด 1: MQTT ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ // โŒ ์ดˆ๋ณด์ž ์ฝ”๋“œ let alertData = [โ€ฆ].sort(โ€ฆ); // ์ดˆ๊ธฐ๋งŒ ์ •๋ ฌ

// โœ… ํ”„๋กœ ์ฝ”๋“œ let alertData = [โ€ฆ]; $: sortedData = alertData.slice().sort(โ€ฆ); // ํ•ญ์ƒ ์ •๋ ฌ

ํŒจํ„ด 2: ์บ์Šค์ผ€์ด๋”ฉ ํ•„ํ„ฐ // โŒ ์ดˆ๋ณด์ž ์ฝ”๋“œ function updateSpaceList() { โ€ฆ } function updateFilteredData() { โ€ฆ }

// โœ… ํ”„๋กœ ์ฝ”๋“œ $: spaceList = selectedFloor === โ€˜allโ€™ ? โ€ฆ : โ€ฆ; $: filteredData = alertData.filter(โ€ฆ);


๐Ÿ“… 2์ฃผ ํ•™์Šต ํ”Œ๋žœ

Week 1: JavaScript ๊ธฐ์ดˆ

์›”: Array.map(), filter() ์—ฐ์Šต ํ™”: Array.reduce() ์—ฐ์Šต ์ˆ˜: ์ •๋ ฌ (sort, localeCompare) ๋ชฉ: Set, ์ˆœ์„œ ๋ณด์žฅ ๊ฐœ๋… ๊ธˆ: ๋ณต์Šต + ํ€ด์ฆˆ ์ฃผ๋ง: ์‹ค์ „ ๊ณผ์ œ (Bldg.svelte ๋ฆฌํŒฉํ† ๋ง)

Week 2: Svelte + ์‹ค์ „

์›”: Reactive statements ($:) ํ™”: $: ์˜์กด์„ฑ ์ถ”์  ์ˆ˜: onMount, onDestroy ๋ชฉ: ์‹ค์ „ ํŒจํ„ด (MQTT) ๊ธˆ: EventLog.svelte ์ง์ ‘ ๊ตฌํ˜„ ์ฃผ๋ง: ์ „์ฒด ๋ณต์Šต


๐ŸŽฏ ํ•™์Šต ๋ฐฉ๋ฒ• ๊ถŒ์žฅ

  1. MDN ๋ฌธ์„œ ์ฝ๋Š” ๋ฒ•

1๏ธโƒฃ ์˜ˆ์ œ๋ถ€ํ„ฐ ์ฝ๊ธฐ (์ด๋ก ์€ ๋‚˜์ค‘์—) 2๏ธโƒฃ ์ฝ˜์†”์—์„œ ์ง์ ‘ ์‹คํ–‰ 3๏ธโƒฃ ๋ณ€ํ˜•ํ•ด๋ณด๊ธฐ (์ˆซ์ž ๋ฐ”๊พธ๊ธฐ, ์กฐ๊ฑด ๋ฐ”๊พธ๊ธฐ) 4๏ธโƒฃ ์ด๋ก  ์ฝ๊ธฐ 5๏ธโƒฃ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉ

  1. ๋งค์ผ 30๋ถ„ ์ฝ”๋”ฉ ์ฑŒ๋ฆฐ์ง€

// ๋งค์ผ ์•„์นจ ๋ฃจํ‹ด const data = [/* ๋žœ๋ค ๋ฐ์ดํ„ฐ */];

// Day 1: map ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ํ•„๋“œ๋งŒ ์ถ”์ถœ // Day 2: filter ์‚ฌ์šฉํ•ด์„œ ์กฐ๊ฑด ํ•„ํ„ฐ๋ง // Day 3: reduce ์‚ฌ์šฉํ•ด์„œ ๊ทธ๋ฃนํ•‘ // โ€ฆ

  1. ์‹œ๋‹ˆ์–ด์—๊ฒŒ ์งˆ๋ฌธํ•˜๊ธฐ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

โœ… MDN ๋ฌธ์„œ ์ฝ์–ด๋ดค๋Š”๊ฐ€? โœ… ์ฝ˜์†”์—์„œ ํ…Œ์ŠคํŠธํ•ด๋ดค๋Š”๊ฐ€? โœ… ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๊ตฌ๊ธ€๋งํ•ด๋ดค๋Š”๊ฐ€? โœ… ๋น„์Šทํ•œ ์ฝ”๋“œ๋ฅผ ํ”„๋กœ์ ํŠธ์—์„œ ์ฐพ์•„๋ดค๋Š”๊ฐ€?


๐Ÿš€ ์ฒซ ์ฃผ ์‹œ์ž‘ํ•˜๊ธฐ

์˜ค๋Š˜ ๋‹น์žฅ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ:

  1. MDN Array.map() ์ฝ๊ธฐ (10๋ถ„)
  2. ์ฝ˜์†” ์—ด๊ณ  ๊ณผ์ œ 1 ํ’€๊ธฐ (20๋ถ„)
  3. Bldg.svelte์—์„œ map() ์ฐพ์•„๋ณด๊ธฐ (10๋ถ„)

์ด 40๋ถ„์ด๋ฉด ์ฒซ ์Šคํ… ์™„๋ฃŒ!

โ€” ๐Ÿ“Š ๋Œ€ํ™” ๋ถ„์„: ์‚ฌ์šฉ์ž๋‹˜์˜ ์งˆ๋ฌธ ํŒจํ„ด

์งˆ๋ฌธ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋ถ„๋ฅ˜

์นดํ…Œ๊ณ ๋ฆฌ ์งˆ๋ฌธ ๋‚ด์šฉ ๋นˆ๋„
JavaScript ๊ธฐ๋ณธ Array methods (map, filter, sort), localeCompare ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด
Svelte ๊ฐœ๋… Reactive statement ($:), ์–ธ์ œ ์‚ฌ์šฉ? ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด
๋ฐ์ดํ„ฐ ํ๋ฆ„ MQTT ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ, ์ •๋ ฌ ํƒ€์ด๋ฐ ๐Ÿ”ด๐Ÿ”ด
๋ธŒ๋ผ์šฐ์ € API history.replaceState, localStorage ๐Ÿ”ด๐Ÿ”ด
์•„ํ‚คํ…์ฒ˜ App.svelte ๋™์ž‘, routes ๋ฐฐ์—ด ์ˆœ์„œ ๐Ÿ”ด
๋””๋ฒ„๊น… โ€œ์™œ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ?โ€, Edge case ๐Ÿ”ด

๐ŸŽฏ ์•ฝ์  ๋ถ„์„

  1. JavaScript ๋ฐฐ์—ด/๊ฐ์ฒด ๋ฉ”์„œ๋“œ ์ดํ•ด ๋ถ€์กฑ ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€œalertData์—์„œ ์ƒˆ ๋ฐฐ์—ด ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•?โ€
  • โ€œlocaleCompare๊ฐ€ ๋ญ์•ผ?โ€
  • โ€œparseInt() vs localeCompare ์ฐจ์ด?โ€
  • โ€œ์ •๋ ฌ ์ฃผ์„์ฒ˜๋ฆฌํ•ด๋„ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™๋”๋ผโ€

๋ฌธ์ œ:

  • Array.map(), filter(), reduce() ๋™์ž‘ ์›๋ฆฌ ๋ถˆ๋ช…ํ™•
  • Set์˜ ์ˆœ์„œ ๋ณด์žฅ ๊ฐœ๋… ๋ชจ๋ฆ„
  • ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ดํ•ด ๋ถ€์กฑ

  1. Svelte Reactive Statement ๊ฐœ๋… ํ˜ผ๋ž€ ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€$: ์—†์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์„๊นŒ?โ€
  • โ€œ์‹œ๋‹ˆ์–ด๋Š” $:๋ฅผ ์‹ซ์–ดํ•˜๋Š” ๊ฒƒ ๊ฐ™์•„โ€
  • โ€œMQTT ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ์ž๋™์œผ๋กœ ์ •๋ ฌ ์•ˆ ๋˜์ง€?โ€

๋ฌธ์ œ:

  • $:์˜ ๋™์ž‘ ์‹œ์  ๋ถˆ๋ช…ํ™•
  • ์–ธ์ œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ํŒ๋‹จ ๋ชป ํ•จ
  • Reactive vs Imperative ์ฐจ์ด ์ดํ•ด ๋ถ€์กฑ

  1. ๋ฐ์ดํ„ฐ ํ๋ฆ„๊ณผ ํƒ€์ด๋ฐ ์ดํ•ด ๋ถ€์กฑ ๐Ÿ”ด๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€œ์ตœ์ดˆ ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ alertData๊ฐ€ ์ž๋™์œผ๋กœ ์ •๋ ฌ ์•ˆ ๋˜์ง€?โ€
  • โ€œMQTT๋กœ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜?โ€

๋ฌธ์ œ:

  • ์ดˆ๊ธฐ ์‹คํ–‰ vs ๋Ÿฐํƒ€์ž„ ์—…๋ฐ์ดํŠธ ์ฐจ์ด ๋ชจ๋ฆ„
  • ๋ถˆ๋ณ€์„ฑ(Immutability) ๊ฐœ๋… ๋ถ€์กฑ

  1. App.svelte ๊ฐ™์€ โ€œํฐ ๊ทธ๋ฆผโ€ ์ดํ•ด ๋ถ€์กฑ ๐Ÿ”ด

์ฆ๊ฑฐ:

  • โ€œApp.svelte๊ฐ€ ํ•˜๋Š” ์ผ์ด ์ดํ•ด๊ฐ€ ์•ˆ ๊ฐ€โ€
  • โ€œroutes[2]๋Š” ์—†๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€?โ€

๋ฌธ์ œ:

  • ์ปดํฌ๋„ŒํŠธ ์ƒ๋ช…์ฃผ๊ธฐ ์ดํ•ด ๋ถ€์กฑ
  • ๋ฐฐ์—ด ์ธ๋ฑ์‹ฑ ๊ธฐ๋ณธ ๊ฐœ๋… ๋ถ€์กฑ

๐Ÿ’ช ๊ฐ•์  ๋ถ„์„

โœ… ์ž˜ํ•˜๋Š” ๊ฒƒ๋“ค

  1. ์งˆ๋ฌธ์„ ์ž˜ ํ•จ: ์ดํ•ด ์•ˆ ๋˜๋ฉด ๋ฐ”๋กœ ๋ฌผ์–ด๋ด„
  2. ์ง์ ‘ ํ…Œ์ŠคํŠธ: ์ฝ”๋“œ ์ˆ˜์ •ํ•˜๊ณ  ์ฝ˜์†” ์ฐ์–ด๋ด„
  3. Step-by-step ์‚ฌ๊ณ : โ€œํ•œ ์ค„์”ฉ ๋˜์งš์–ด ๊ฐ€๋ฉด์„œ ๋™์ž‘ ์ ๊ฒ€โ€
  4. ํ”ผ๋“œ๋ฐฑ ์ˆ˜์šฉ: ์‹œ๋‹ˆ์–ด ์กฐ์–ธ ์ ๊ทน ๋ฐ˜์˜

๐Ÿ“š ๋งž์ถคํ˜• ํ•™์Šต ์ปค๋ฆฌํ˜๋Ÿผ

๐ŸŽ“ Phase 1: JavaScript ๊ธฐ์ดˆ ๋‹ค์ง€๊ธฐ (1-2์ฃผ)

Week 1: ๋ฐฐ์—ด ์™„๋ฒฝ ์ •๋ณต

Day 1-2: ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ ๊ธฐ๋ณธ

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 1: alertData์—์„œ ์ธต ๋ชฉ๋ก ์ถ”์ถœ (์ค‘๋ณต ์ œ๊ฑฐ) const alertData = [ { floorName: โ€˜1Fโ€™, status: โ€˜Alertโ€™ }, { floorName: โ€˜2Fโ€™, status: โ€˜Closedโ€™ }, { floorName: โ€˜1Fโ€™, status: โ€˜Offlineโ€™ }, ];

// TODO: Set ์‚ฌ์šฉํ•ด์„œ [โ€˜1Fโ€™, โ€˜2Fโ€™] ๋งŒ๋“ค๊ธฐ const floors = [โ€ฆnew Set(alertData.map(a => a.floorName))]; console.log(floors);

// ๊ณผ์ œ 2: Status๋ณ„ ๊ฐœ์ˆ˜ ์„ธ๊ธฐ // ๊ฒฐ๊ณผ: { Alert: 1, Closed: 1, Offline: 1 } const statusCount = alertData.reduce((acc, item) => { acc[item.status] = (acc[item.status] || 0) + 1; return acc; }, {});

Day 3-4: ์ •๋ ฌ๊ณผ ๋น„๊ต

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 3: ๋‹ค์–‘ํ•œ ์ •๋ ฌ ๋ฐฉ๋ฒ• ๋น„๊ต const floors = [โ€˜10Fโ€™, โ€˜2Fโ€™, โ€˜1Fโ€™, โ€˜B1โ€™, โ€˜Roofโ€™];

// ๋ฐฉ๋ฒ• 1: ๊ธฐ๋ณธ ์ •๋ ฌ (๋ฌธ์ž์—ด) console.log([โ€ฆfloors].sort()); // ๊ฒฐ๊ณผ: [โ€˜1Fโ€™, โ€˜10Fโ€™, โ€˜2Fโ€™, โ€˜B1โ€™, โ€˜Roofโ€™] โ† 10F๊ฐ€ 2F ์•ž์—!

// ๋ฐฉ๋ฒ• 2: localeCompare console.log([โ€ฆfloors].sort((a, b) => a.localeCompare(b))); // ๊ฒฐ๊ณผ: ๊ฐ™์Œ

// ๋ฐฉ๋ฒ• 3: localeCompare + numeric console.log([โ€ฆfloors].sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))); // ๊ฒฐ๊ณผ: [โ€˜1Fโ€™, โ€˜2Fโ€™, โ€˜10Fโ€™, โ€˜B1โ€™, โ€˜Roofโ€™] โ† ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ!

// ๊ณผ์ œ 4: ์™œ ์ด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์ƒ๊ธฐ๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ

Day 5: Set๊ณผ ์ˆœ์„œ

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set
  • ๋ธ”๋กœ๊ทธ: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set#%EC%84%A4%EB%AA%85

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 5: Set์˜ ์ˆœ์„œ ์ดํ•ดํ•˜๊ธฐ const data = [ { time: โ€˜09:00:02โ€™, floor: โ€˜3Fโ€™ }, { time: โ€˜09:00:01โ€™, floor: โ€˜1Fโ€™ }, { time: โ€˜09:00:01โ€™, floor: โ€˜2Fโ€™ }, ];

// Q: Set์€ ์‚ฝ์ž… ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•œ๋‹ค. ๊ฒฐ๊ณผ๋Š”? const floors1 = [โ€ฆnew Set(data.map(a => a.floor))]; console.log(โ€˜์ •๋ ฌ ์ „:โ€™, floors1); // [โ€˜3Fโ€™, โ€˜1Fโ€™, โ€˜2Fโ€™]

// Q: ๋ฐ์ดํ„ฐ๋ฅผ ๋จผ์ € ์ •๋ ฌํ•˜๋ฉด? const sortedData = data.sort((a, b) => a.floor.localeCompare(b.floor, undefined, { numeric: true })); const floors2 = [โ€ฆnew Set(sortedData.map(a => a.floor))]; console.log(โ€˜์ •๋ ฌ ํ›„:โ€™, floors2); // [โ€˜1Fโ€™, โ€˜2Fโ€™, โ€˜3Fโ€™]

// ๊ฒฐ๋ก : Set์€ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜์ง€๋งŒ, ์ž…๋ ฅ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•œ๋‹ค!


Week 2: ๊ฐ์ฒด์™€ ์ฐธ์กฐ

Day 1-2: ์–•์€ ๋ณต์‚ฌ vs ๊นŠ์€ ๋ณต์‚ฌ

  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Spread_syntax
  • MDN: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 6: ๋ถˆ๋ณ€์„ฑ ์ดํ•ดํ•˜๊ธฐ let alertData = [ { time: โ€˜09:00:01โ€™, status: โ€˜Alertโ€™ } ];

// โŒ ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ• (์›๋ณธ ๋ณ€๊ฒฝ) alertData.push({ time: โ€˜09:00:02โ€™, status: โ€˜Closedโ€™ });

// โœ… ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ• (์ƒˆ ๋ฐฐ์—ด ์ƒ์„ฑ) alertData = [โ€ฆalertData, { time: โ€˜09:00:02โ€™, status: โ€˜Closedโ€™ }];

// Svelte์—์„œ๋Š” ์™œ ํ›„์ž๋ฅผ ์„ ํ˜ธํ• ๊นŒ? (๋ฐ˜์‘์„ฑ ๋•Œ๋ฌธ!)

Day 3-5: ๋ธŒ๋ผ์šฐ์ € API

  • MDN: https://developer.mozilla.org/ko/docs/Web/API/History_API
  • MDN: https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 7: URL ๋ณ€๊ฒฝ ์—†์ด ์ƒํƒœ ์—…๋ฐ์ดํŠธ // ํ˜„์žฌ URL: http://localhost:5173/floor/1?spaceID=3

// history.replaceState๋กœ ์ฟผ๋ฆฌ์ŠคํŠธ๋ง ์ œ๊ฑฐ const newUrl = window.location.pathname; window.history.replaceState(null, โ€˜โ€™, newUrl); // ๊ฒฐ๊ณผ: http://localhost:5173/floor/1

// ๊ณผ์ œ 8: localStorage ํ™œ์šฉ localStorage.setItem(โ€˜selectedFloorโ€™, โ€˜2Fโ€™); const floor = localStorage.getItem(โ€˜selectedFloorโ€™); console.log(floor); // โ€˜2Fโ€™


๐ŸŽ“ Phase 2: Svelte ํ•ต์‹ฌ ๊ฐœ๋… (1์ฃผ)

Day 1-3: Reactive Statements ์™„์ „ ์ •๋ณต

  • https://svelte.dev/tutorial/reactive-declarations
  • https://svelte.dev/docs/svelte-components#script-3-$-marks-a-statement-as-reactive

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 9: $:์˜ ๋™์ž‘ ์‹œ์  ์ดํ•ด let count = 0;

// Q1: ์ด ์ฝ”๋“œ๋Š” ์–ธ์ œ ์‹คํ–‰๋ ๊นŒ? $: doubled = count * 2; $: console.log(โ€˜count changed:โ€™, count);

// Q2: ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋ช‡ ๋ฒˆ ์‹คํ–‰๋ ๊นŒ? function increment() { count += 1; count += 1; count += 1; } // ๋‹ต: console.log๋Š” 1๋ฒˆ๋งŒ ์‹คํ–‰! (Svelte๊ฐ€ batch ์ฒ˜๋ฆฌ)

// ๊ณผ์ œ 10: ์˜์กด์„ฑ ์ดํ•ด let firstName = โ€˜Johnโ€™; let lastName = โ€˜Doeโ€™;

$: fullName = ${firstName} ${lastName}; // Q: firstName๋งŒ ๋ฐ”๋€Œ๋ฉด? โ†’ fullName ์žฌ๊ณ„์‚ฐ // Q: lastName๋งŒ ๋ฐ”๋€Œ๋ฉด? โ†’ fullName ์žฌ๊ณ„์‚ฐ // Q: ๋‘˜ ๋‹ค ์•ˆ ๋ฐ”๋€Œ๋ฉด? โ†’ ์žฌ๊ณ„์‚ฐ ์•ˆ ํ•จ

Day 4-5: ์ƒ๋ช…์ฃผ๊ธฐ

  • https://svelte.dev/tutorial/onmount
  • https://svelte.dev/tutorial/ondestroy

์‹ค์Šต ๊ณผ์ œ: // ๊ณผ์ œ 11: onMount vs $: ์ฐจ์ด let data = [];

// ๋ฐฉ๋ฒ• 1: onMount onMount(() => { data = fetchData(); // 1๋ฒˆ๋งŒ ์‹คํ–‰ });

// ๋ฐฉ๋ฒ• 2: $: $: { data = fetchData(); // data๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์‹คํ–‰ (๋ฌดํ•œ ๋ฃจํ”„!) }

// Q: ์–ธ์ œ onMount๋ฅผ ์“ฐ๊ณ , ์–ธ์ œ $:๋ฅผ ์“ธ๊นŒ?


๐ŸŽ“ Phase 3: ์‹ค์ „ ํŒจํ„ด (์ง„ํ–‰ ์ค‘)

์ง€๊ธˆ ์ž‘์—…ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋กœ ํ•™์Šต

ํŒจํ„ด 1: MQTT ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ // โŒ ์ดˆ๋ณด์ž ์ฝ”๋“œ let alertData = [โ€ฆ].sort(โ€ฆ); // ์ดˆ๊ธฐ๋งŒ ์ •๋ ฌ

// โœ… ํ”„๋กœ ์ฝ”๋“œ let alertData = [โ€ฆ]; $: sortedData = alertData.slice().sort(โ€ฆ); // ํ•ญ์ƒ ์ •๋ ฌ

ํŒจํ„ด 2: ์บ์Šค์ผ€์ด๋”ฉ ํ•„ํ„ฐ // โŒ ์ดˆ๋ณด์ž ์ฝ”๋“œ function updateSpaceList() { โ€ฆ } function updateFilteredData() { โ€ฆ }

// โœ… ํ”„๋กœ ์ฝ”๋“œ $: spaceList = selectedFloor === โ€˜allโ€™ ? โ€ฆ : โ€ฆ; $: filteredData = alertData.filter(โ€ฆ);


๐Ÿ“… 2์ฃผ ํ•™์Šต ํ”Œ๋žœ

Week 1: JavaScript ๊ธฐ์ดˆ

์›”: Array.map(), filter() ์—ฐ์Šต ํ™”: Array.reduce() ์—ฐ์Šต ์ˆ˜: ์ •๋ ฌ (sort, localeCompare) ๋ชฉ: Set, ์ˆœ์„œ ๋ณด์žฅ ๊ฐœ๋… ๊ธˆ: ๋ณต์Šต + ํ€ด์ฆˆ ์ฃผ๋ง: ์‹ค์ „ ๊ณผ์ œ (Bldg.svelte ๋ฆฌํŒฉํ† ๋ง)

Week 2: Svelte + ์‹ค์ „

์›”: Reactive statements ($:) ํ™”: $: ์˜์กด์„ฑ ์ถ”์  ์ˆ˜: onMount, onDestroy ๋ชฉ: ์‹ค์ „ ํŒจํ„ด (MQTT) ๊ธˆ: EventLog.svelte ์ง์ ‘ ๊ตฌํ˜„ ์ฃผ๋ง: ์ „์ฒด ๋ณต์Šต


๐ŸŽฏ ํ•™์Šต ๋ฐฉ๋ฒ• ๊ถŒ์žฅ

  1. MDN ๋ฌธ์„œ ์ฝ๋Š” ๋ฒ•

1๏ธโƒฃ ์˜ˆ์ œ๋ถ€ํ„ฐ ์ฝ๊ธฐ (์ด๋ก ์€ ๋‚˜์ค‘์—) 2๏ธโƒฃ ์ฝ˜์†”์—์„œ ์ง์ ‘ ์‹คํ–‰ 3๏ธโƒฃ ๋ณ€ํ˜•ํ•ด๋ณด๊ธฐ (์ˆซ์ž ๋ฐ”๊พธ๊ธฐ, ์กฐ๊ฑด ๋ฐ”๊พธ๊ธฐ) 4๏ธโƒฃ ์ด๋ก  ์ฝ๊ธฐ 5๏ธโƒฃ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉ

  1. ๋งค์ผ 30๋ถ„ ์ฝ”๋”ฉ ์ฑŒ๋ฆฐ์ง€

// ๋งค์ผ ์•„์นจ ๋ฃจํ‹ด const data = [/* ๋žœ๋ค ๋ฐ์ดํ„ฐ */];

// Day 1: map ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ํ•„๋“œ๋งŒ ์ถ”์ถœ // Day 2: filter ์‚ฌ์šฉํ•ด์„œ ์กฐ๊ฑด ํ•„ํ„ฐ๋ง // Day 3: reduce ์‚ฌ์šฉํ•ด์„œ ๊ทธ๋ฃนํ•‘ // โ€ฆ

  1. ์‹œ๋‹ˆ์–ด์—๊ฒŒ ์งˆ๋ฌธํ•˜๊ธฐ ์ „ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

โœ… MDN ๋ฌธ์„œ ์ฝ์–ด๋ดค๋Š”๊ฐ€? โœ… ์ฝ˜์†”์—์„œ ํ…Œ์ŠคํŠธํ•ด๋ดค๋Š”๊ฐ€? โœ… ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๊ตฌ๊ธ€๋งํ•ด๋ดค๋Š”๊ฐ€? โœ… ๋น„์Šทํ•œ ์ฝ”๋“œ๋ฅผ ํ”„๋กœ์ ํŠธ์—์„œ ์ฐพ์•„๋ดค๋Š”๊ฐ€?


๐Ÿš€ ์ฒซ ์ฃผ ์‹œ์ž‘ํ•˜๊ธฐ

์˜ค๋Š˜ ๋‹น์žฅ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ:

  1. MDN Array.map() ์ฝ๊ธฐ (10๋ถ„)
  2. ์ฝ˜์†” ์—ด๊ณ  ๊ณผ์ œ 1 ํ’€๊ธฐ (20๋ถ„)
  3. Bldg.svelte์—์„œ map() ์ฐพ์•„๋ณด๊ธฐ (10๋ถ„)

์ด 40๋ถ„์ด๋ฉด ์ฒซ ์Šคํ… ์™„๋ฃŒ!


This line appears after every note.

Notes mentioning this note

There are no notes linking to this note.


Here are all the notes in this garden, along with their links, visualized as a graph.