<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발 여행자</title>
    <link>https://yeshyun.tistory.com/</link>
    <description>개발자와 PM 그 사이</description>
    <language>ko</language>
    <pubDate>Sat, 13 Jun 2026 12:25:47 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>예스현</managingEditor>
    <image>
      <title>개발 여행자</title>
      <url>https://tistory1.daumcdn.net/tistory/4967340/attach/858fd5377b9e4f10b5fd7e287684f8fe</url>
      <link>https://yeshyun.tistory.com</link>
    </image>
    <item>
      <title>[IT/SW 직무] 취준 50전 6승 후기 (현대자동차 최종합격)</title>
      <link>https://yeshyun.tistory.com/62</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 하반기 첫 회사 취업에 성공하고 2024년 하반기에 현회사로 이직했지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제서야 취준 후기를 작성해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 이야기하면 총 1년에 걸쳐 취준을 했고(23년 하반기, 24년 상/하반기)&lt;br /&gt;50개 회사 지원 -&amp;gt; &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;6개 회사에 최종합격&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;23년 하반기: 서류 48개 / 최종합격 5개 &lt;u&gt;&lt;b&gt; &lt;/b&gt;&lt;/u&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 23년 하반기 취업 결과를 정리하면 서류는 인턴을 포함하여 총 47개를 넣었고 5개 회사 최종합격을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당시 주요 IT 기업들은 채용이 막혀서 넣지 못했다는 건 조금 아쉬웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  지원회사 (48개)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;  &lt;/span&gt;&lt;b&gt;제조업(12개) &lt;br /&gt;: &lt;/b&gt;LG화학, 현대자동차, 현대모비스, KAI 한국항공우주산업, 삼성전자, SK하이닉스, GS칼텍스, 기아, LIG넥스원, 한화시스템, 한화글로벌, HD현대사이트솔루션&lt;/li&gt;
&lt;li&gt;&lt;span&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;IT(15개)&lt;br /&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;LG CNS, LG전자, SK텔레콤, 엔씨소프트, 현대글로비스, CJ CGV, SK C&amp;amp;C, KT, 아프리카TV, 대한상공회의소, 농협정보시스템, KT cloud, 넥토리얼, 롯데정보통신, 카카오, 토스뱅크&lt;/li&gt;
&lt;li&gt;&lt;span&gt;  &lt;/span&gt;&lt;b&gt;금융업(20개) &lt;br /&gt;: &lt;/b&gt;새마을금고중앙회, DB금융투자, 한국투자증권, 신한은행, 신한카드, 키움증권, 현대차증권, 현대해상, 신한투자증권, 하나은행, 우리카드, 교보증권, NH투자증권, 카카오페이, 당근페이, 신한라이프, NH농협은행, 신한ez손해보험, 롯데카드, 한화생명&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  서류탈락 (19개) - 남은서류: 29/48&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;LG화학 &lt;/b&gt;SW&lt;/span&gt;&amp;nbsp;- 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;DB금융투자&lt;/b&gt;&lt;/span&gt; IT - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;현대자동차&lt;/b&gt;&lt;/span&gt; UX개발 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;현대모비스&lt;/b&gt;&lt;/span&gt; 스마트팩토리 플랫폼 개발 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;엔씨소프트&lt;/b&gt;&lt;/span&gt; PM - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;한국투자증권&lt;/b&gt;&lt;/span&gt; 플랫폼 FE개발 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;키움증권&lt;/b&gt;&lt;/span&gt; IT - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;현대차증권&lt;/b&gt;&lt;/span&gt; IT - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;현대해상&lt;/b&gt;&lt;/span&gt; IT 웹기획 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;SK하이닉스&lt;/b&gt;&lt;/span&gt; 양산기술 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;기아&lt;/b&gt;&lt;/span&gt; 고객경험 상품 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;KT&lt;/b&gt;&lt;/span&gt; - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;대한상공회의소&lt;/b&gt;&lt;/span&gt; - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;한화글로벌&lt;/b&gt;&lt;/span&gt; IT기획 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;우리카드&lt;/b&gt;&lt;/span&gt; 디지털 - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;NH투자증권&lt;/b&gt;&lt;/span&gt; IT - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;신한라이프 &lt;/b&gt;IT&lt;/span&gt; - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;당근페이&lt;/b&gt;&lt;/span&gt; Data Analyst - 서류탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;한화생명&lt;/b&gt;&lt;/span&gt; IT- 서류탈락&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;본격적으로 자기소개서를 쓰기 전 그동안의 대외활동/&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;프로젝트를 나열했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 아래 양식에 따라 프로젝트들을 복기하면서 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;첫번 째 프로젝트) OOO 인턴십 / FE 개발&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;보여준능력 : 리더십, &lt;u&gt;&lt;b&gt;비효율개선&lt;/b&gt;&lt;/u&gt;, 협업, 어려움&lt;/li&gt;
&lt;li&gt;왜?&lt;/li&gt;
&lt;li&gt;어떻게?&lt;/li&gt;
&lt;li&gt;힘든점?&lt;/li&gt;
&lt;li&gt;어떻게 극복?&lt;/li&gt;
&lt;li&gt;배운점?&lt;/li&gt;
&lt;li&gt;성과?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 정리해두면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;'성과 - 힘든점 - 어떻게 극복 - 배운점'&lt;/u&gt; 순으로 자기소개서를 작성하기만 하면 되어 시간절약에 큰 도움이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(면접 준비할 때도 큰 도움)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 초반에는 지원동기 항목을 작성하는 게 가장 어려웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 세운 전략은 모든 회사를 조사하면서 지원동기를 쓰기는 어려우니 IT/SW 직무 지원동기로 초점을 맞췄다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를들어 금융업과 제조업은 아예 다른 업종인데 직무는 동일했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 세부 업무는 다르겠지만 IT/SW 개발 직무라는건 다르지 않으니, IT/SW 직무에 지원한 동기를 서술했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덕분에 회사마다 2~3문장만 수정하며 지원동기를 작성할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방학에 자소서 준비하는 팁은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼성전자, 하이닉스 이력서와 자기소개서 작성해보는 것을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 회사들에 비해 이력서와 자기소개서 항목이 복잡하고 양이 많아서 준비해두면 다른 회사 지원할 때 큰 도움이 될 것이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  필기 / 코딩테스트 탈락 및 불참(16개) &lt;b&gt;- 남은서류:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;13/48&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;새마을금고중앙회&lt;/b&gt;&lt;/span&gt; IT 인적성 - 필기탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;LG CNS&lt;/b&gt;&lt;/span&gt; 코테 - 필기탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;SK텔레콤&lt;/b&gt;&lt;/span&gt; FE개발 - 필기탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;신한카드&lt;/b&gt;&lt;/span&gt; IT - 필기탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;삼성전자&lt;/b&gt;&lt;/span&gt; 신호시스템 - 필기탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;GS칼텍스&lt;/b&gt;&lt;/span&gt; IT - 필기탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;신한투자증권&lt;/b&gt;&lt;/span&gt; IT - 코테불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;LG전자&lt;/b&gt;&lt;/span&gt; HE SW - 코테불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;농정시&lt;/b&gt;&lt;/span&gt; IT - 코테불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;NH농협은행&lt;/b&gt;&lt;/span&gt; IT - 코테불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;롯데정보통신&lt;/b&gt;&lt;/span&gt; IT - 코테불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;카카오&lt;/b&gt;&lt;/span&gt; FE 인턴 - 코테불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;대한상공회의소 &lt;/b&gt;IT&lt;/span&gt;&amp;nbsp;- 코테탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;SK C&amp;amp;C&lt;/b&gt;&lt;/span&gt; SW개발 - 코테탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;넥토리얼&lt;/b&gt;&lt;/span&gt; 웹애플리케이션 - 코테탈락&lt;/li&gt;
&lt;li&gt;&lt;b&gt;토스뱅크&lt;/b&gt; FE개발 - 코테탈락&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서류를 많이 작성한 만큼 코딩테스트/필기 시험이 겹치는 곳도 많아 포기해야 해서 아쉬웠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;취준생 시절에는 서류합격 하나가 소중했기에..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;코딩테스트&lt;/b&gt;는 꾸준히 백준, 프로그래머스를 통해 준비했고, 금융권 생각이 있었기에 SQL 문제도 꾸준히 풀었었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 금융권 생각이 있으면 프로그래머스에서 SQL 문제를 꼭 많이 풀어보기를 추천한다.&lt;/p&gt;
&lt;figure id=&quot;og_1772953378831&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/parts/17046&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dg6BfB/dJMb85vMXDz/IqVUKXa6uHBBP73HRPRth0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cTgrUB/dJMb84XWLvJ/SyuRX1tpLRAiWcSk2FQFSK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/parts/17046&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/parts/17046&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dg6BfB/dJMb85vMXDz/IqVUKXa6uHBBP73HRPRth0/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cTgrUB/dJMb84XWLvJ/SyuRX1tpLRAiWcSk2FQFSK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 SQL이랑 알고리즘 문제가 섞여서 나오는데,&lt;br /&gt;SQL은 Lv3~4 무난히 풀 수 있어야 합격권이었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 알고리즘에 자신이 없어서 SQL에서 점수를 더 얻으려고 노력했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필기시험(GSAT, SKCT 등)은&lt;/b&gt;&amp;nbsp;공부를 거의 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;막학기에 12학점과 졸업논문을 병행해야 했기에 2~3일 공부한 게 전부였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필기는 공부량과 비례해서 점수가 오른다는데.. 공부를 못하고 필기 시험을 본 게 아쉬웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 선택과 집중의 중요성을 다시 한 번 깨달았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  면접 탈락 / 불참(8개) &lt;b&gt;- 남은서류:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;5/48&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;현대글로비스&lt;/b&gt;&lt;/span&gt; IT시스템 기획 - 1차면접불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;LIG넥스원&lt;/b&gt;&lt;/span&gt; IPS - 1차면접불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;신한ez손해보험 &lt;/b&gt;IT기획&lt;/span&gt;&amp;nbsp;- 1차면접불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;KT cloud&lt;/b&gt;&lt;/span&gt; - 1차면접탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;카카오페이&lt;/b&gt;&lt;/span&gt; FE개발 인턴 - 1차면접탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;신한은행&lt;/b&gt;&lt;/span&gt; ICT - 1차면접탈락&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;CJ CGV&lt;/b&gt;&lt;/span&gt; IT - 최종불참&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;하나은행&lt;/b&gt;&lt;/span&gt; IT - 최종탈락&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접도 필기와 마찬가지로 겹치는 곳이 있어 포기한 곳들이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접은 다대다와 1:N인 케이스가 있었는데, 나는 다대다 면접이 더 편했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 지원자들이 대답하는 시간에 숨 고르며 생각 정리도 할 수 있고 저렇게 대답할 수도 있구나 하며 공부가 됐었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 내가 붙을지 안붙을지 예측이 조금은 가능했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 면까몰이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기억나는 면접은 &lt;b&gt;HD현대사이트솔루션&lt;/b&gt;, &lt;b&gt;하나은행, 신한은행&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HD현대사이트솔루션&lt;/b&gt;은 분당GRC가 근무지이자 면접장이었는데 사옥이 엄청 웅장했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 특히나 회사 선택에 있어 사옥 시설이 중요했는데, 다른 세계에 들어온 느낌이 들 정도로 사옥이 정말 멋있어서 기억에 남았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 면접장에서 학교 동기와 선배님을 만나서 반갑고 신기했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하나은행&lt;/b&gt;은 &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;1차 면접장이 연수원이었는데 여기도 역시나 시설이 너무 좋았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접선물도 주고, 인생네컷 찍을 수 있는 곳도 있고.. 세심하게 지원자들을 위해 준비했다는 게 느껴졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나은행은 PT면접이 있어서 사전에 면접스터디를 2주일 정도 참여했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 스터디에서 준비했던 주제와 비슷한 게 나와서 자신감 있게 발표했고, 면접관 분들께 칭찬을 받았던 기억이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1772954227690&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;하나금융연구소&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.hanaif.re.kr&quot; data-og-source-url=&quot;https://www.hanaif.re.kr/boardList.do?menuId=&amp;amp;tabMenuId=MN1106&quot; data-og-url=&quot;https://www.hanaif.re.kr/boardList.do?menuId=&amp;amp;tabMenuId=MN1106&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.hanaif.re.kr/boardList.do?menuId=&amp;amp;tabMenuId=MN1106&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hanaif.re.kr/boardList.do?menuId=&amp;amp;tabMenuId=MN1106&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;하나금융연구소&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hanaif.re.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나은행 면접 준비하는 분들은 '&lt;b&gt;하나금융연구소&lt;/b&gt;' 디지털 분야 정독하는 것을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 너무 도움 많이 되었던 PT면접 준비 팁 영상. 강민혁 강사님 강추!!&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=DOvCIrwMPbQ&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cLI3mW/dJMb9lL9zzO/1peZTI8arlrKfF8DeCXp2k/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=472_184_676_406,https://scrap.kakaocdn.net/dn/eBbGt/dJMb9lL9zzN/RZIDMzlZbGiZTORkOSSKkK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=472_184_676_406,https://scrap.kakaocdn.net/dn/bJjguK/dJMb9kT00iu/3JZSUDWVZg7j4mf4WmuAyK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=472_184_676_406&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;PT면접 평가요소 및 발표 템플릿/시나리오_피티 면접 실전 활용&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/DOvCIrwMPbQ&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신한은행은 비대면으로 1차면접을 봤고 비대면 면접은 처음인지라 어떻게 봐야할지 감이 안잡혔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대한 셔츠 입고 방 책상에 앉아 스탠드 키고 면접을 봤는데 내가 생각해도 준비성과 간절함(?)이 떨어져 보였다.&lt;br /&gt;그래서 이후에 있는 화상면접들은 &lt;b&gt;인터뷰박스 &lt;/b&gt;공간에서 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어렵게 얻은 면접 기회이고 1~2만원에 예약이 가능하니 인터뷰박스 예약해서 보는 걸 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  최종합격 (5개)&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;KAI 한국항공우주산업&lt;/b&gt;&lt;/span&gt; 시뮬레이터 SW개발 - 최종합격&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;한화시스템&lt;/b&gt;&lt;/span&gt; 서비스개발 - 최종합격&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;아프리카TV&lt;/b&gt;&lt;/span&gt; FE개발 - 최종합격&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;HD현대사이트솔루션&lt;/b&gt;&lt;/span&gt; ICT - 최종합격&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;교보증권&lt;/b&gt;&lt;/span&gt; IT 개발 - 최종합격&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;1325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l78Cu/dJMcajuBKFC/apGZDaWIr0MxaUvzlagTa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l78Cu/dJMcajuBKFC/apGZDaWIr0MxaUvzlagTa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l78Cu/dJMcajuBKFC/apGZDaWIr0MxaUvzlagTa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl78Cu%2FdJMcajuBKFC%2FapGZDaWIr0MxaUvzlagTa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;536&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;1325&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4개월의 힘든 시간끝에 최종적으로 5개 기업에 최종합격했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직무, 근무지, 연봉, 복지, 커리어.. 많은 것을 고려하여 한 회사에 입사했고 정말 많은 걸 배웠던 시간이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;욕심만 내면 내가 하고싶은 일을 전부 할 수 있다는 게 가장 큰 장점이었고, 사수님이랑 팀원들이 너무 잘해주셔 의지를 많이 했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 회사가 아쉬웠기 보다는 가고싶던 회사를 못갔다는 게 아쉬운 마음이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학기와 병행하며 선택과 집중을 하지 못했기에 내 역량을 전부 보여주지 못했다는 아쉬움이기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;24년 상반기: 서류 1개 / 최종합격 0개&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 삼성전자 리서치 SW개발&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 회사도 충분히 경력 쌓기 좋겠다고 생각했기에 1개만 지원했었다. &lt;br /&gt;삼성전자 리서치는 직무가 핏하지는 않아서 몇 분만에 작성하고 지원해봤는데 역시나 서류탈락이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간절함이 없었던 것 같기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;24년 하반기: 서류 1개 / 최종합격 1개  &lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 현대자동차 SW개발&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㄴ 채용 프로세스&lt;br /&gt;: 서류 -&amp;gt; 1차 직무면접 및 인성검사 -&amp;gt; 2차 종합면접 -&amp;gt; &lt;u&gt;최종합격&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq4P9A/dJMcahQ5Ik5/IMhysKGXkviUuYdYpZJe11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq4P9A/dJMcahQ5Ik5/IMhysKGXkviUuYdYpZJe11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq4P9A/dJMcahQ5Ik5/IMhysKGXkviUuYdYpZJe11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq4P9A%2FdJMcahQ5Ik5%2FIMhysKGXkviUuYdYpZJe11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;306&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이곳은 인턴을 넣었다가 면접에서 떨어진 경험이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;석사 이상을 주로 뽑는다는 소문을 들었고 직무도 핏했기에 서류에 하나라도 더 적으려 했었는데 이게 오히려 독이 되었다고 생각했다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 다음번 지원했을 때는 &lt;b&gt;&lt;u&gt;직무와 연관있는 경험들로만 간결하게&lt;/u&gt;&lt;/b&gt; 적으려고 노력했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 회사를 다니고 있었기에 오히려 마음 놓고 지원하고 면접도 볼 수 있었기에 좋은 결과를 얻은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 다니면서 자격증 공부도 했어야 해서 사실상 필기/코테 준비는 하지 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마침 SW개발 직무인데도 코딩테스트가 없어서 밑져야 본전이라는 마음으로 지원해보았는데 최종합격을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 취준은 운9 실력1인가보다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신 1차 직무면접때 PT면접이 있었는데 꽤나 어려웠던 기억이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예상치 못한 문제가 나와서 PT 자료를 잘 준비하지 못했고 사실 떨어질 줄 알았다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도저히 생각이 안나서 임기응변으로 다른 쪽으로 방향을 틀어서 답변을 준비했지만 쉽지 않은 면접이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 좋게 봐주셔서 1차 면접을 합격할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현대자동차 지원 후기는 다른 게시글로 기록하는걸로.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;궁금한 점은 댓글로 남겨주시면 도움드릴 수 있는 한 답변 드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;모든 취준생을 응원합니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>취업준비</category>
      <category>IT 직무 취업</category>
      <category>sk하이닉스</category>
      <category>SW개발 취업</category>
      <category>금융권 취업</category>
      <category>삼성전자</category>
      <category>취업준비</category>
      <category>취업후기</category>
      <category>취준일기</category>
      <category>프론트엔드 개발 취업</category>
      <category>현대자동차</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/62</guid>
      <comments>https://yeshyun.tistory.com/62#entry62comment</comments>
      <pubDate>Sun, 8 Mar 2026 16:42:18 +0900</pubDate>
    </item>
    <item>
      <title>SPA, MPA, PWA&amp;hellip; 웹 아키텍처</title>
      <link>https://yeshyun.tistory.com/61</link>
      <description>&lt;h2 data-end=&quot;346&quot; data-start=&quot;323&quot; data-ke-size=&quot;size26&quot;&gt;1. 웹 아키텍처, 어디까지 왔나&lt;/h2&gt;
&lt;p data-end=&quot;438&quot; data-start=&quot;348&quot; data-ke-size=&quot;size16&quot;&gt;웹은 정적인 HTML에서 시작해, 이제는 앱처럼 동작하는 복잡한 시스템으로 진화했다. 이 과정에서 다양한 아키텍처가 등장했고, 각각의 방식은 시대적 요구와 기술 환경에 따라 선택되었다. 이 글에서는 현재 주목받는 SPA, MPA, PWA를 중심으로 어떤 아키텍처가 앞으로 주류가 될지 살펴본다.&lt;/p&gt;
&lt;hr data-end=&quot;528&quot; data-start=&quot;525&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;549&quot; data-start=&quot;530&quot; data-ke-size=&quot;size26&quot;&gt;2. SPA: 앱 같은 웹&lt;/h2&gt;
&lt;p data-end=&quot;606&quot; data-start=&quot;551&quot; data-ke-size=&quot;size16&quot;&gt;SPA는 한 번의 페이지 로딩 이후, 필요한 데이터만 비동기적으로 불러와 화면을 갱신. &lt;br /&gt;대표적인 기술은 React, Vue, Angular 등이 있으며, UX 측면에서 빠른 반응성과 모바일 친화적인 구조로 주목받고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;916&quot; data-start=&quot;821&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;847&quot; data-start=&quot;821&quot;&gt;&lt;b&gt;장점&lt;/b&gt;: 빠른 전환, 모바일 친화적&lt;/li&gt;
&lt;li data-end=&quot;876&quot; data-start=&quot;848&quot;&gt;&lt;b&gt;단점&lt;/b&gt;: 초기 로딩 느림, SEO 이슈&lt;/li&gt;
&lt;li data-end=&quot;916&quot; data-start=&quot;877&quot;&gt;&lt;b&gt;대표 사례&lt;/b&gt;: Gmail, Facebook, Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uah0o/btsNBbzveOC/Cp4k7VA5KCcS6QKpEubXO0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uah0o/btsNBbzveOC/Cp4k7VA5KCcS6QKpEubXO0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uah0o/btsNBbzveOC/Cp4k7VA5KCcS6QKpEubXO0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuah0o%2FbtsNBbzveOC%2FCp4k7VA5KCcS6QKpEubXO0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;398&quot; height=&quot;217&quot; data-origin-width=&quot;550&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;732&quot; data-start=&quot;729&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;754&quot; data-start=&quot;734&quot; data-ke-size=&quot;size26&quot;&gt;3. MPA: 전통의 재조명&lt;/h2&gt;
&lt;p data-end=&quot;1072&quot; data-start=&quot;964&quot; data-ke-size=&quot;size16&quot;&gt;MPA는 전통적인 방식으로, 요청할 때마다 새로운 HTML 페이지를 로딩한다. &lt;br /&gt;서버 사이드 렌더링이 기본이기 때문에 SEO에 강하고, 초기 로딩이 빠르다는 점에서 최근 다시 주목받고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1178&quot; data-start=&quot;1074&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1103&quot; data-start=&quot;1074&quot;&gt;&lt;b&gt;장점&lt;/b&gt;: SEO 최적화, 초기 속도 빠름&lt;/li&gt;
&lt;li data-end=&quot;1138&quot; data-start=&quot;1104&quot;&gt;&lt;b&gt;단점&lt;/b&gt;: 페이지 간 전환 느림, 복잡한 상태 관리&lt;/li&gt;
&lt;li data-end=&quot;1178&quot; data-start=&quot;1139&quot;&gt;&lt;b&gt;대표 사례&lt;/b&gt;: 쇼핑몰, 뉴스 사이트 등 콘텐츠 중심 사이트&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;799&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpqhPO/btsNzZ8bqHe/1D05fqYhWVYI0WGsYdPhQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpqhPO/btsNzZ8bqHe/1D05fqYhWVYI0WGsYdPhQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpqhPO/btsNzZ8bqHe/1D05fqYhWVYI0WGsYdPhQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpqhPO%2FbtsNzZ8bqHe%2F1D05fqYhWVYI0WGsYdPhQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;325&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;799&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;931&quot; data-start=&quot;928&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;956&quot; data-start=&quot;933&quot; data-ke-size=&quot;size26&quot;&gt;4. PWA: 웹이 앱을 닮아간다&lt;/h2&gt;
&lt;p data-end=&quot;1001&quot; data-start=&quot;958&quot; data-ke-size=&quot;size16&quot;&gt;웹앱인데 앱처럼 동작.&lt;br /&gt;오프라인, 푸시 알림, 홈 화면 설치까지 가능.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1055&quot; data-start=&quot;1003&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1017&quot; data-start=&quot;1003&quot;&gt;설치 없이 앱 UX&lt;/li&gt;
&lt;li data-end=&quot;1029&quot; data-start=&quot;1018&quot;&gt;오프라인 동작&lt;/li&gt;
&lt;li data-end=&quot;1045&quot; data-start=&quot;1030&quot;&gt;브라우저 호환성 이슈&lt;/li&gt;
&lt;li data-end=&quot;1055&quot; data-start=&quot;1046&quot;&gt;구현 복잡&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1127&quot; data-start=&quot;1124&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1164&quot; data-start=&quot;1129&quot; data-ke-size=&quot;size26&quot;&gt;5. SPA + SSR, JAMstack: 조합의 시대&lt;/h2&gt;
&lt;p data-end=&quot;1234&quot; data-start=&quot;1166&quot; data-ke-size=&quot;size16&quot;&gt;SPA의 단점을 보완하기 위해 SSR, SSG가 결합됨.&lt;br /&gt;Next.js, Nuxt.js 등은 이런 흐름의 대표주자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1310&quot; data-start=&quot;1236&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1259&quot; data-start=&quot;1236&quot;&gt;SSR: SEO + 초기 로딩 개선&lt;/li&gt;
&lt;li data-end=&quot;1277&quot; data-start=&quot;1260&quot;&gt;SSG: 빠른 정적 배포&lt;/li&gt;
&lt;li data-end=&quot;1310&quot; data-start=&quot;1278&quot;&gt;JAMstack: Headless CMS + CDN&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1385&quot; data-start=&quot;1382&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1402&quot; data-start=&quot;1387&quot; data-ke-size=&quot;size26&quot;&gt;6. 트렌드와 전망&lt;/h2&gt;
&lt;p data-end=&quot;1438&quot; data-start=&quot;1404&quot; data-ke-size=&quot;size16&quot;&gt;앞으로는 하나의 방식이 아닌, 목적에 따라 조합형이 대세.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1530&quot; data-start=&quot;1440&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1468&quot; data-start=&quot;1440&quot;&gt;콘텐츠 중심 &amp;rarr; MPA or JAMstack&lt;/li&gt;
&lt;li data-end=&quot;1492&quot; data-start=&quot;1469&quot;&gt;인터랙션 중심 &amp;rarr; SPA + SSR&lt;/li&gt;
&lt;li data-end=&quot;1510&quot; data-start=&quot;1493&quot;&gt;앱 경험 강조 &amp;rarr; PWA&lt;/li&gt;
&lt;li data-end=&quot;1530&quot; data-start=&quot;1511&quot;&gt;하이브리드 &amp;rarr; 대부분의 실무&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1601&quot; data-start=&quot;1598&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1626&quot; data-start=&quot;1603&quot; data-ke-size=&quot;size26&quot;&gt;7. 결론: 목적이 방향을 정한다&lt;/h2&gt;
&lt;p data-end=&quot;1684&quot; data-start=&quot;1628&quot; data-ke-size=&quot;size16&quot;&gt;기술의 우열은 없다.&lt;br /&gt;중요한 건 &quot;무엇을 만들 것인가&quot;.&lt;br /&gt;아키텍처는 도구일 뿐, 정답은 없다.&lt;/p&gt;
&lt;p data-end=&quot;1747&quot; data-start=&quot;1691&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS/웹</category>
      <category>MPA</category>
      <category>pwa</category>
      <category>spa</category>
      <category>웹아키텍처</category>
      <category>프론트엔드 웹</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/61</guid>
      <comments>https://yeshyun.tistory.com/61#entry61comment</comments>
      <pubDate>Sat, 26 Apr 2025 16:57:26 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] EC2로 배포한 서버를 HTTPS로 연결하기</title>
      <link>https://yeshyun.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;❗️어떤 문제가 발생했을까&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1693790891873&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Mixed Content: The page at 'https://yeshyun-git-master-shgus1224.vercel.app/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://~~&amp;rsquo;. This request has been blocked; the content must be served over HTTPS.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;http://www.yeshyun.site&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;포트폴리오 사이트&lt;/a&gt; 만들고 AWS에 서버를 배포한 이후 에러가 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;이전&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;846&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KSnMo/btssP8Ebc6r/40qmog5KNbC076D3PWXpkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KSnMo/btssP8Ebc6r/40qmog5KNbC076D3PWXpkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KSnMo/btssP8Ebc6r/40qmog5KNbC076D3PWXpkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKSnMo%2FbtssP8Ebc6r%2F40qmog5KNbC076D3PWXpkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;523&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;846&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;이후&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/O0gNb/btss3KnD33x/pIccjeBWEpK8M2TInZJaz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/O0gNb/btss3KnD33x/pIccjeBWEpK8M2TInZJaz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/O0gNb/btss3KnD33x/pIccjeBWEpK8M2TInZJaz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FO0gNb%2Fbtss3KnD33x%2FpIccjeBWEpK8M2TInZJaz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;219&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;클라이언트단에서 사진을 불러오는 방법으로 간단히 해결하면 되지만&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나름 서버공부를 해보겠다고 자신감 있게 서버를 구축하고 배포했는데 에러가 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;분명 로컬에서는 잘 작동했는데!!&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Vercel에 배포된 클라이언트와 AWS에 배포한 node 서버 사이 소통이 잘 안되는 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1693790884258&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Mixed Content: The page at 'https://yeshyun-git-master-shgus1224.vercel.app/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://~~&amp;rsquo;. This request has been blocked; the content must be served over HTTPS.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;❓ 왜 오류가 발생했을까&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 에러는 암호화되지 않은 HTTP 서버에 암호화된 HTTP&lt;b&gt;S&lt;/b&gt; 페이지를 요청할 때 발생한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;참고로 Vercel로 배포한 클라이언트는 HTTPS, API는 HTTP다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해당 경고를 제거하기 위해서는 html 파일에 아래 메타 태그를 추가하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1693791858486&quot; class=&quot;routeros&quot; style=&quot;background-color: #f6f7f8; color: #555555; text-align: start;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;meta http-equiv=&quot;Content-Security-Policy&quot; content=&quot;upgrade-insecure-requests&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 여전히 사진을 불러오지 못하고 다른 에러가 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1693791876597&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;net::R_SSL_PROTOCOL_ERROR&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;이 오류를 해결하기 위해서는 배포한 서버가 http로 설정되어 있어서, 이를 &lt;span style=&quot;color: #ee2323;&quot;&gt;https로 수정해야된다.&lt;/span&gt; &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;이를 위해서는 도메인을 사서 AWS 로드밸런서를 이용해야한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;  어떻게 해결할까&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 가비아에서 도메인 구매&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://www.gabia.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.gabia.com/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693792409549&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;웹을 넘어 클라우드로. 가비아&quot; data-og-description=&quot;그룹웨어부터 멀티클라우드까지 하나의 클라우드 허브&quot; data-og-host=&quot;www.gabia.com&quot; data-og-source-url=&quot;https://www.gabia.com/&quot; data-og-url=&quot;https://www.gabia.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/TBnhL/hyTPz726Iz/wrCE8u6xe3ir8UKpGzLfh1/img.jpg?width=1200&amp;amp;height=1000&amp;amp;face=0_0_1200_1000&quot;&gt;&lt;a href=&quot;https://www.gabia.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.gabia.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/TBnhL/hyTPz726Iz/wrCE8u6xe3ir8UKpGzLfh1/img.jpg?width=1200&amp;amp;height=1000&amp;amp;face=0_0_1200_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;웹을 넘어 클라우드로. 가비아&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;그룹웨어부터 멀티클라우드까지 하나의 클라우드 허브&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.gabia.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;API 주소는 외부로 노출되지 않고 학생이어서 저렴하고 무난한 .shop 도메인을 구매했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. Route 53에 접속하여 호스팅 영역생성&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/route53/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://aws.amazon.com/ko/route53/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693794709754&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;company&quot; data-og-title=&quot;Amazon Route 53 | DNS 서비스 | AWS&quot; data-og-description=&quot;Amazon Route 53는 가용성과 확장성이 뛰어난 도메인 이름 시스템(DNS) 웹 서비스입니다. Route 53는 사용자 요청을 AWS 또는 온프레미스에서 실행되는 인터넷 애플리케이션에 연결합니다.&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/route53/&quot; data-og-url=&quot;https://aws.amazon.com/ko/route53/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/du4HuA/hyTPz8bGYz/ZA3gqHWMEJki1ePJSKQfNk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ynFDe/hyTPwKo8g8/4lYH5IzI3aZZkmRK4x5SHK/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/rLBpd/hyTPvLuL2j/fXdQdV3Jd869GHsunonb4K/img.png?width=2360&amp;amp;height=1320&amp;amp;face=0_0_2360_1320&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/route53/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://aws.amazon.com/ko/route53/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/du4HuA/hyTPz8bGYz/ZA3gqHWMEJki1ePJSKQfNk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ynFDe/hyTPwKo8g8/4lYH5IzI3aZZkmRK4x5SHK/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/rLBpd/hyTPvLuL2j/fXdQdV3Jd869GHsunonb4K/img.png?width=2360&amp;amp;height=1320&amp;amp;face=0_0_2360_1320');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Amazon Route 53 | DNS 서비스 | AWS&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Amazon Route 53는 가용성과 확장성이 뛰어난 도메인 이름 시스템(DNS) 웹 서비스입니다. Route 53는 사용자 요청을 AWS 또는 온프레미스에서 실행되는 인터넷 애플리케이션에 연결합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2yB67/btssTgaCpAk/6i4NQulT53gQw1VkkMCl91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2yB67/btssTgaCpAk/6i4NQulT53gQw1VkkMCl91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2yB67/btssTgaCpAk/6i4NQulT53gQw1VkkMCl91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2yB67%2FbtssTgaCpAk%2F6i4NQulT53gQw1VkkMCl91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1230&quot; height=&quot;342&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;AWS Route 53에 접속하여 '호스팅 영역 생성'을 클릭한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1210&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rq73N/btssSrcpgvx/kTRptM1vguZy0kj26Pc8R1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rq73N/btssSrcpgvx/kTRptM1vguZy0kj26Pc8R1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rq73N/btssSrcpgvx/kTRptM1vguZy0kj26Pc8R1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frq73N%2FbtssSrcpgvx%2FkTRptM1vguZy0kj26Pc8R1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1210&quot; height=&quot;848&quot; data-origin-width=&quot;1210&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;'도메인 이름'란에 &lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구매한 도메인 이름 입력 및 '퍼블릭 호스팅 영역'을 클릭한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. 레코드 생성&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;1302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kwzz2/btssVIKLJNQ/zwwWr7WOkBgpydRplsmDuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kwzz2/btssVIKLJNQ/zwwWr7WOkBgpydRplsmDuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kwzz2/btssVIKLJNQ/zwwWr7WOkBgpydRplsmDuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fkwzz2%2FbtssVIKLJNQ%2FzwwWr7WOkBgpydRplsmDuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;624&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;1302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;호스팅 영역에서 자신이 입력한 도메인을 클릭하면 다음과 같은 페이지에 들어갈 수 있고 &lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;'레코드 생성' 버튼을 클릭한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t7VKz/btssVIDZSQ7/ZfYK2EfYsCyaCFNTnrNANk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t7VKz/btssVIDZSQ7/ZfYK2EfYsCyaCFNTnrNANk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t7VKz/btssVIDZSQ7/ZfYK2EfYsCyaCFNTnrNANk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft7VKz%2FbtssVIDZSQ7%2FZfYK2EfYsCyaCFNTnrNANk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1252&quot; height=&quot;280&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;값 부분에 자신이 생성한 'EC2 PUBILC IP'값을 기재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 후 레코드 생성 버튼 클릭한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4. 가비아에서 구매한 도메인과 연결&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1iSdD/btss3XURdUQ/mqQAQOKdWsyMpm8YV99bD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1iSdD/btss3XURdUQ/mqQAQOKdWsyMpm8YV99bD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1iSdD/btss3XURdUQ/mqQAQOKdWsyMpm8YV99bD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1iSdD%2Fbtss3XURdUQ%2FmqQAQOKdWsyMpm8YV99bD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1212&quot; height=&quot;522&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;NS 유형에 나와있는 4개의 값들을 가비아 도메인 네임서버에 붙여넣으면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;가비아 네임서버 목록은 아래와 같이&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;'My 가비아 -&amp;gt; 본인이 구매한 도메인의 관리버튼 -&amp;gt; 네임서버 설정' 목록 에서 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PiSY0/btssUNr2HW8/YkzJFv1cnszhf2Y6iXJiWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PiSY0/btssUNr2HW8/YkzJFv1cnszhf2Y6iXJiWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PiSY0/btssUNr2HW8/YkzJFv1cnszhf2Y6iXJiWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPiSY0%2FbtssUNr2HW8%2FYkzJFv1cnszhf2Y6iXJiWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1242&quot; height=&quot;350&quot; data-origin-width=&quot;1242&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5. AWS Certificate manager 인증서 요청&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhEJhx/btssVVpNzZT/7YNBOBpekgO7UpmWs80PBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhEJhx/btssVVpNzZT/7YNBOBpekgO7UpmWs80PBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhEJhx/btssVVpNzZT/7YNBOBpekgO7UpmWs80PBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhEJhx%2FbtssVVpNzZT%2F7YNBOBpekgO7UpmWs80PBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;540&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AWS Certificate manager 인증서 요청인증서 요청하고 기본설정대로 다음을 선택하면 도메인 이름을 기재하는 창이 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bla1Ij/btssThgjIir/AAPZut0BuUXTBK9hLGGQI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bla1Ij/btssThgjIir/AAPZut0BuUXTBK9hLGGQI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bla1Ij/btssThgjIir/AAPZut0BuUXTBK9hLGGQI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbla1Ij%2FbtssThgjIir%2FAAPZut0BuUXTBK9hLGGQI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1216&quot; height=&quot;512&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아까 가비아에서 구매한 도메인 명을 입력한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 후 다른 설정은 건드리지 않고 다음으로 넘어간다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mg7VQ/btssSDcQBcN/Ch06LRi6BKTF77FnjL0cvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mg7VQ/btssSDcQBcN/Ch06LRi6BKTF77FnjL0cvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mg7VQ/btssSDcQBcN/Ch06LRi6BKTF77FnjL0cvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMg7VQ%2FbtssSDcQBcN%2FCh06LRi6BKTF77FnjL0cvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1068&quot; height=&quot;266&quot; data-origin-width=&quot;1068&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그러면 다음과 같이 '검증대기 중' 상태를 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인증서 아이디를 클릭하면 &amp;lsquo;Route 53에서 레코드 생성&amp;rsquo; 버튼을 확인할 수 있고 이를 클릭한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsefHr/btss3Ens1YF/4yhCFoC8RNlnSPoKac1tT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsefHr/btss3Ens1YF/4yhCFoC8RNlnSPoKac1tT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsefHr/btss3Ens1YF/4yhCFoC8RNlnSPoKac1tT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsefHr%2Fbtss3Ens1YF%2F4yhCFoC8RNlnSPoKac1tT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1220&quot; height=&quot;250&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 자동으로 Route 53에서 설정한 도메인을 인식하여 인증이 진행된다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6. Target Group 인증서 요청&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로드 밸런서에 적용하기 위한 Target Group을 만들어줘야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;EC2 페이지에서 왼쪽 하단의 로드 밸런싱 부분에 대상 그룹을 선택한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NwVbn/btss3ZrCKBq/KsdYeYk1IJAaqG5oWAaZmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NwVbn/btss3ZrCKBq/KsdYeYk1IJAaqG5oWAaZmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NwVbn/btss3ZrCKBq/KsdYeYk1IJAaqG5oWAaZmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNwVbn%2Fbtss3ZrCKBq%2FKsdYeYk1IJAaqG5oWAaZmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1228&quot; height=&quot;264&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 Create target group 버튼을 눌러준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8mXlK/btssVVcikIE/AlbCpiWqjmtvTqo0Bg0Jk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8mXlK/btssVVcikIE/AlbCpiWqjmtvTqo0Bg0Jk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8mXlK/btssVVcikIE/AlbCpiWqjmtvTqo0Bg0Jk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8mXlK%2FbtssVVcikIE%2FAlbCpiWqjmtvTqo0Bg0Jk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1206&quot; height=&quot;360&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Choose a target type에서 instances를 선택한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VE8VP/btssYR1JrXF/0nMyGLA6ABHkHUw3fPfV5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VE8VP/btssYR1JrXF/0nMyGLA6ABHkHUw3fPfV5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VE8VP/btssYR1JrXF/0nMyGLA6ABHkHUw3fPfV5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVE8VP%2FbtssYR1JrXF%2F0nMyGLA6ABHkHUw3fPfV5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1212&quot; height=&quot;792&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 주의할 점! &lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;포트 번호는 직접 실행할 서비스의 포트번호이다. &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;즉 본인이 서버의 포트를 8080번을 사용한다면 80번이아닌 8080번을 넣어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkSNyN/btssVIKMJmx/WWPtIpnvu1JiVIA1ptunl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkSNyN/btssVIKMJmx/WWPtIpnvu1JiVIA1ptunl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkSNyN/btssVIKMJmx/WWPtIpnvu1JiVIA1ptunl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkSNyN%2FbtssVIKMJmx%2FWWPtIpnvu1JiVIA1ptunl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1228&quot; height=&quot;506&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;적용할 인스턴스를 체크하고 아래의 Include as pending below 버튼을 눌러준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 후 Create target group 버튼을 눌러 target group을 생성해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;7.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로드밸런서&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;ec2-로드 밸런서&lt;/b&gt;에 들어와서 로드 밸런서 생성 버튼을 눌러준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi6hen/btss722ERPh/JiRCoQ61z2GrAgCKY8kpKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi6hen/btss722ERPh/JiRCoQ61z2GrAgCKY8kpKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi6hen/btss722ERPh/JiRCoQ61z2GrAgCKY8kpKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi6hen%2Fbtss722ERPh%2FJiRCoQ61z2GrAgCKY8kpKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1176&quot; height=&quot;294&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1218&quot; data-origin-height=&quot;746&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zcnBr/btss3Zd4pjt/3kOIxiMzBbhNerFeDYSF90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zcnBr/btss3Zd4pjt/3kOIxiMzBbhNerFeDYSF90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zcnBr/btss3Zd4pjt/3kOIxiMzBbhNerFeDYSF90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzcnBr%2Fbtss3Zd4pjt%2F3kOIxiMzBbhNerFeDYSF90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1218&quot; height=&quot;746&quot; data-origin-width=&quot;1218&quot; data-origin-height=&quot;746&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;맨 왼쪽의 '&lt;b&gt;Application Load Balancer'&lt;/b&gt;를 클릭한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bliDd9/btssSDYgDdB/zwttf0MkRukkjX35dwDTLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bliDd9/btssSDYgDdB/zwttf0MkRukkjX35dwDTLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bliDd9/btssSDYgDdB/zwttf0MkRukkjX35dwDTLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbliDd9%2FbtssSDYgDdB%2Fzwttf0MkRukkjX35dwDTLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1176&quot; height=&quot;582&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 후 원하는 &lt;b&gt;'Load balancer name'&lt;/b&gt;을 입력한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 부분에서 주의할 점이 있다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;가용영역을 선택하는 부분인데&amp;nbsp;&lt;b&gt;본인의 인스턴스의 가용영역이 반드시 포함되어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVhMrx/btss8jQQnjK/bEoCkAUclN6wSS6fHJJ7I0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVhMrx/btss8jQQnjK/bEoCkAUclN6wSS6fHJJ7I0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVhMrx/btss8jQQnjK/bEoCkAUclN6wSS6fHJJ7I0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVhMrx%2Fbtss8jQQnjK%2FbEoCkAUclN6wSS6fHJJ7I0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1146&quot; height=&quot;176&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;가용영역은 ec2의 인스턴스에서 확인이 가능하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zmp5Q/btss8l8XRvG/64xBXq91URztBDp5TotHF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zmp5Q/btss8l8XRvG/64xBXq91URztBDp5TotHF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zmp5Q/btss8l8XRvG/64xBXq91URztBDp5TotHF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fzmp5Q%2Fbtss8l8XRvG%2F64xBXq91URztBDp5TotHF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1144&quot; height=&quot;436&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;보안 그룹은 본인의 인스턴스와 같은 보안 그룹을 사용하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 또다른 주의사항은 &lt;b&gt;보안 규칙에 https이 등록되어 있어야한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMsTge/btssTgPgmkp/bSOatqyOdIVpBE41T0GQ80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMsTge/btssTgPgmkp/bSOatqyOdIVpBE41T0GQ80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMsTge/btssTgPgmkp/bSOatqyOdIVpBE41T0GQ80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMsTge%2FbtssTgPgmkp%2FbSOatqyOdIVpBE41T0GQ80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1152&quot; height=&quot;610&quot; data-origin-width=&quot;1152&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Listeners and routing 가장 핵심인 부분이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;HTTP, HTTPS 프로토콜 리스너에 위에서 만든 &lt;b&gt;'Target Group'&lt;/b&gt;을 선택해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 후 앞서 받은 인증서를 등록을 해줍니다. 필자는&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 인증서 등록에 시간이 걸려서 여기서 조금 지체되었다. (약 3시간)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1138&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBxA3H/btssTr32Xgt/6qyZdFsuBL8aePyTK4Nbs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBxA3H/btssTr32Xgt/6qyZdFsuBL8aePyTK4Nbs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBxA3H/btssTr32Xgt/6qyZdFsuBL8aePyTK4Nbs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBxA3H%2FbtssTr32Xgt%2F6qyZdFsuBL8aePyTK4Nbs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1138&quot; height=&quot;246&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1138&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btZn6E/btss3KnGPWQ/OnTm7fdquzrAAYOAElFOB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btZn6E/btss3KnGPWQ/OnTm7fdquzrAAYOAElFOB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btZn6E/btss3KnGPWQ/OnTm7fdquzrAAYOAElFOB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtZn6E%2Fbtss3KnGPWQ%2FOnTm7fdquzrAAYOAElFOB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1142&quot; height=&quot;274&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인증서 발급 상태가 발급됨으로 변경되었으면 다시 이어서 진행하면된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOQc6i/btssTfv1rUT/hR0SZK4Ja8MiSF5fBMfLi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOQc6i/btssTfv1rUT/hR0SZK4Ja8MiSF5fBMfLi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOQc6i/btssTfv1rUT/hR0SZK4Ja8MiSF5fBMfLi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOQc6i%2FbtssTfv1rUT%2FhR0SZK4Ja8MiSF5fBMfLi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1142&quot; height=&quot;318&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인증서를 선택하고 다음을 클릭하면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;드디어 로드밸런스 생성이 완료된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;8. 도메인 설정&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMyC9p/btssPxcWGb1/q40qyak0Fn1U8EsFKzElyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMyC9p/btssPxcWGb1/q40qyak0Fn1U8EsFKzElyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMyC9p/btssPxcWGb1/q40qyak0Fn1U8EsFKzElyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMyC9p%2FbtssPxcWGb1%2Fq40qyak0Fn1U8EsFKzElyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1130&quot; height=&quot;206&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Route53&lt;/b&gt;으로 돌아가서 도메인 이름을 눌러준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼 다음과 같은 화면이 나올텐데 '레코드 생성 버튼'을 클릭한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3TT0V/btssPvGbhMS/VYoNzQnQvzMMm6WKXEAzXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3TT0V/btssPvGbhMS/VYoNzQnQvzMMm6WKXEAzXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3TT0V/btssPvGbhMS/VYoNzQnQvzMMm6WKXEAzXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3TT0V%2FbtssPvGbhMS%2FVYoNzQnQvzMMm6WKXEAzXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1158&quot; height=&quot;302&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필자는 백엔드 도메인을 위해 앞에 api를 입력했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;레코드 유형은 그대로 A로 두면되고 &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;별칭 버튼을 눌러서 위와같이 선택한 후 3번째 줄에 아까 만들어놓은 로드 밸런서를 등록한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 서울로 지정하고 로드밸런서를 선택하려고 했는데, &lt;b&gt;목록이 나오지 않는 문제&lt;/b&gt;가 있었다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러가지를 시도했는데.. 결론은 필자의 인스턴스 리전은 유럽(스톡홀름)이었다(!) &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리전 수정 후 다시 시도하니 목록이 잘 나오는 것을 확인할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;마지막으로 맽 밑 다음을 클릭하면 끝이났다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  결과&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 후 포스트맨을 이용하여 테스트를 진행해보았는데 문제가 해결되지 않았다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서칭 결과 보안그룹에서 https랑 http를 열어주지 않아서 발생한 문제였고 보안그룹 목록에 들어가 수정만 해주면 해결된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2156&quot; data-origin-height=&quot;1114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IW314/btssVMNa0Os/CWqdwL8Uvs9cv76J2qqtkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IW314/btssVMNa0Os/CWqdwL8Uvs9cv76J2qqtkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IW314/btssVMNa0Os/CWqdwL8Uvs9cv76J2qqtkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIW314%2FbtssVMNa0Os%2FCWqdwL8Uvs9cv76J2qqtkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2156&quot; height=&quot;1114&quot; data-origin-width=&quot;2156&quot; data-origin-height=&quot;1114&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2142&quot; data-origin-height=&quot;1242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6BfH3/dJMcaf6PDaJ/cbWQ7RA3cJueAwHBPgjfPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6BfH3/dJMcaf6PDaJ/cbWQ7RA3cJueAwHBPgjfPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6BfH3/dJMcaf6PDaJ/cbWQ7RA3cJueAwHBPgjfPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6BfH3%2FdJMcaf6PDaJ%2FcbWQ7RA3cJueAwHBPgjfPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2142&quot; height=&quot;1242&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2142&quot; data-origin-height=&quot;1242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 잘 나오는 것을 확인할 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 포트폴리오 사이트를 재개편 하면서 서버를 사용하지 않지만, AWS를 이용해서 로드밸러서 기능을 사용해볼 수 있는 좋은 기회였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP/HTTPS 네트워크 관련해서 공부를 많이 해봐야겠다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>대외활동/Amazon Student Club 1기</category>
      <category>AWS 로드밸런서</category>
      <category>but requested an insecure XMLHttpRequest endpoint 'http://~~&amp;rsquo;. This request has been blocked; the content must be served over HTTPS.</category>
      <category>EC2 HTTPS로 연결</category>
      <category>loaded over HTTPS</category>
      <category>net::R_SSL_PROTOCOL_ERROR</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/60</guid>
      <comments>https://yeshyun.tistory.com/60#entry60comment</comments>
      <pubDate>Mon, 4 Sep 2023 12:21:50 +0900</pubDate>
    </item>
    <item>
      <title>React-Query : refetchOnWindowFocus 이슈 해결과정 (feat. API 재호출)</title>
      <link>https://yeshyun.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 이슈 발생&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query 도입 이후 로그인 페이지에서 사용되는 Input 컴포넌트 리팩터링 도중에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;동일한 API를 여러번 호출하는 이슈를 발견했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2870&quot; data-origin-height=&quot;1508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vdoCZ/btsq5c8Pzs5/k5ZArzFYP9dIuj92oktGL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vdoCZ/btsq5c8Pzs5/k5ZArzFYP9dIuj92oktGL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vdoCZ/btsq5c8Pzs5/k5ZArzFYP9dIuj92oktGL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvdoCZ%2Fbtsq5c8Pzs5%2Fk5ZArzFYP9dIuj92oktGL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2870&quot; height=&quot;1508&quot; data-origin-width=&quot;2870&quot; data-origin-height=&quot;1508&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개발자 도구의 네트워크 탭을 확인하면 동일한 API가 여러번 호출된 것을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이런 상황이 발생하는 경우는 다른 인터넷 창, 탭, 어플리케이션에 방문했다가 돌아오면 API를 재요청하는 것이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;알고보니 Background Refetch라는 개념이 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 어떻게 해결했나?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 id=&quot;background-refetch&quot; style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;- Background Refetch &lt;/b&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(feat. refetchOnWindowFocus)&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b64uyF/btsrgp6Uc2s/NtRAVi55OPbinYlLBBLqCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b64uyF/btsrgp6Uc2s/NtRAVi55OPbinYlLBBLqCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b64uyF/btsrgp6Uc2s/NtRAVi55OPbinYlLBBLqCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb64uyF%2Fbtsrgp6Uc2s%2FNtRAVi55OPbinYlLBBLqCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;694&quot; height=&quot;163&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Background Refetch란 브라우저가 해당 캐시에 대한 데이터를 재요청하는 것으로, &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이를 통해 캐시가 항상 최신의 상태를 유지하도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;- refetchOnWindowFocus&amp;nbsp;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;refetchOnWindowFocus 옵션은 굳이 새로고침을 하지 않아도 캐시의 상태가 stale인 경우 window에 focus를 하면 (인터넷 탭 이동 or 다른 앱 사용 후 창으로 되돌아오기) 자동으로 refetch가 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;설정할 수 있는 값은 3가지가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;true(default)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;false&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;always&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;react-query에서는 window에 focus시&amp;nbsp;&lt;b&gt;데이터가 stale상태인 경우&lt;/b&gt;&amp;nbsp;자동으로 refetch되는&lt;b&gt; true가 기본값&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;false로 바꾸면 창을 벗어나도 새로고침하지 않는 이상 refetch되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;always는 문자 그대로 항상 refetch를 한다.(fresh 상태일 때도)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. 최종 수정사항&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1691999976263&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export const useGetRoomInfo = (roomUUID: string) =&amp;gt; {
  return useQuery(
    [QUERY_KEYS.ROOM.GET_ROOM_INFO, roomUUID],
    () =&amp;gt; getRoomInfo(roomUUID),
    {
      retry: false,
      refetchOnWindowFocus: false, // false로 설정
    }
  );
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 다음과 같이 refetchOnWindowFocus의 옵션값을 false로 설정했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;retry는 이와는 무관하지만, API 요청에 실패했을 때 재요청을 하지않는 옵션값이다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2880&quot; data-origin-height=&quot;1584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GkHsR/btsrauA5G8Z/Jn40Cyalo67KbjJ4WEltNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GkHsR/btsrauA5G8Z/Jn40Cyalo67KbjJ4WEltNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GkHsR/btsrauA5G8Z/Jn40Cyalo67KbjJ4WEltNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGkHsR%2FbtsrauA5G8Z%2FJn40Cyalo67KbjJ4WEltNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2880&quot; height=&quot;1584&quot; data-origin-width=&quot;2880&quot; data-origin-height=&quot;1584&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;결과를 보면 처음 한 번만 요청하고, 이후에는 window에 refoucs 되어도 API를 재호출 하지않는다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;react-query에 다양한 옵션이 있음을 다시 한 번 깨닫고, 지속적으로 공부하면서 리팩터링을 진행해야겠음을 느꼈다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>대외활동/DND 8기</category>
      <category>React Query</category>
      <category>refetchOnWindowFocus</category>
      <category>리액트 쿼리</category>
      <category>모두의시간</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/59</guid>
      <comments>https://yeshyun.tistory.com/59#entry59comment</comments>
      <pubDate>Mon, 14 Aug 2023 17:05:39 +0900</pubDate>
    </item>
    <item>
      <title>[모두의시간] React-Query 도입기</title>
      <link>https://yeshyun.tistory.com/58</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;react-query&amp;nbsp;도입기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;모두의 시간 프로젝트를 짧은 기한 내에 개발하면서 유지보수의 필요성을 크게 느끼고 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메인 개발을 전부 마친 이후에 공통 컴포넌트를 우선적으로 재정돈하고 react-query를 도입했다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bydkVd/btsqDRit0EI/kdLMJkWkeDaeKv1FX7qkG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bydkVd/btsqDRit0EI/kdLMJkWkeDaeKv1FX7qkG0/img.png&quot; style=&quot;width: 32.3698%; margin-right: 10px;&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;1470&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.14&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bydkVd/btsqDRit0EI/kdLMJkWkeDaeKv1FX7qkG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbydkVd%2FbtsqDRit0EI%2FkdLMJkWkeDaeKv1FX7qkG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;816&quot; height=&quot;1470&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJtA8U/btsqCqMrYDo/wK2iL4YbLMl8FJJGlwMyO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJtA8U/btsqCqMrYDo/wK2iL4YbLMl8FJJGlwMyO0/img.png&quot; style=&quot;width: 32.9701%; margin-right: 10px;&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;1468&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.76&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJtA8U/btsqCqMrYDo/wK2iL4YbLMl8FJJGlwMyO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJtA8U%2FbtsqCqMrYDo%2FwK2iL4YbLMl8FJJGlwMyO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;1468&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRCd21/btsqBHnG7z7/eLZV7Kxs5dZ3Bvzi5lqYB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRCd21/btsqBHnG7z7/eLZV7Kxs5dZ3Bvzi5lqYB0/img.png&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;1468&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.3345%;&quot; data-widthpercent=&quot;33.1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRCd21/btsqBHnG7z7/eLZV7Kxs5dZ3Bvzi5lqYB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRCd21%2FbtsqBHnG7z7%2FeLZV7Kxs5dZ3Bvzi5lqYB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;814&quot; height=&quot;1468&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;약속 초대 페이지 -&amp;gt; 로그인 페이지 -&amp;gt; 일정등록 페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wI0bP/btsqESuFl9f/3kGy9YzUWDz2xnspj3rqyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wI0bP/btsqESuFl9f/3kGy9YzUWDz2xnspj3rqyk/img.png&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;1474&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;51.33&quot; style=&quot;width: 50.731%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wI0bP/btsqESuFl9f/3kGy9YzUWDz2xnspj3rqyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwI0bP%2FbtsqESuFl9f%2F3kGy9YzUWDz2xnspj3rqyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;856&quot; height=&quot;1474&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6cyFP/btsqBxlf2VR/RrrlcTaA3jr8ZCcZfytsn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6cyFP/btsqBxlf2VR/RrrlcTaA3jr8ZCcZfytsn1/img.png&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;1460&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;48.67&quot; style=&quot;width: 48.1062%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6cyFP/btsqBxlf2VR/RrrlcTaA3jr8ZCcZfytsn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6cyFP%2FbtsqBxlf2VR%2FRrrlcTaA3jr8ZCcZfytsn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;804&quot; height=&quot;1460&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;실시간 조율현황 페이지 -&amp;gt; 우선순위 보기 페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Query를 도입 해야겠다고 생각한 가장 큰 이유 중 하나는 API를 요청해야 하는 페이지가 하나 둘 늘어났고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useEffct, async await, try catch, loading state... 코드의 줄 수가 불필요하게 길어지고 복잡해졌기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 생성한 방의 정보를 불러오는 API를 호출하는 페이지가 많은데, 데이터가 업데이트 되지 않았을 때는 일정시간 내에는 동일한 데이터를 사용하는게 맞다고 판단했다. API 요청을 최소화 하고싶었고, 추후 방생성하는 페이지들은&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퍼널 형식으로 리팩터링 할 예정이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메인 기능을 사용하기 위해 방문하는 페이지마다 API를 요청하고 있었고, 데이터가 업데이트 되지 않았을 때는 실시간으로 불러오지 않아도 되기에 react query의 캐시 기능을 사용하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;또한 &lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;기존에 Redux, Mobx, Recoil과 같은 다양하고 훌륭한 상태 관리 라이브러리들이 있긴 하지만, 클라이언트 쪽의 데이터들을 관리하기에 적합할 순 있어도 서버 쪽의 데이터들을 관리하기에는 적합하지 않은 점들이 있었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SWR vs React Query&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리액트 쿼리를 도입하기 이전에 패칭 라이브러리의 양대산맥인 SWR과 React-Query 중에&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;어떤 데이터 패칭 라이브러리를 도입할지 고민했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;두 라이브러리 모두 React 환경에서 API 요청을 쉽게 다루기 위한 라이브러리이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;데이터 요청 관련인 loading, success, error 등의 상태를 쉽게 관리하고 cache 기능을 제공하여 불필요한 요청을 줄여준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;SWR은 주로 데이터를 가져오는 것에 설계가 되었기에 설정이 단순하고 라이브러리가 가볍고 &lt;/span&gt;&lt;span&gt;번들 사이즈는 4.3KB이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;React Query는 더 다양한 캐싱전략을 보유하고 커스터마이징 기능을 제공하여 번들 사이즈가 13KB이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2080&quot; data-origin-height=&quot;1272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uN6WY/btsqwVNwVEf/IsuJnDXQ4P6kivVD5TdDR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uN6WY/btsqwVNwVEf/IsuJnDXQ4P6kivVD5TdDR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uN6WY/btsqwVNwVEf/IsuJnDXQ4P6kivVD5TdDR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuN6WY%2FbtsqwVNwVEf%2FIsuJnDXQ4P6kivVD5TdDR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;589&quot; height=&quot;360&quot; data-origin-width=&quot;2080&quot; data-origin-height=&quot;1272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 일반적으로 서비스에서 데이터를 가져오고 캐싱하는 간단한 방법이 필요한 경우 SWR을 선택하는 것이 좋고,&lt;/span&gt;&lt;span&gt;React-Query는 고급 기능이 필요하거나 데이터 종속성이 많은 서비스에서 작업하는 경우가 좋은 선택이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;743&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bguxa7/btsrdhOXowQ/6pt1VLF8g51AjRtRJprjnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bguxa7/btsrdhOXowQ/6pt1VLF8g51AjRtRJprjnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bguxa7/btsrdhOXowQ/6pt1VLF8g51AjRtRJprjnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbguxa7%2FbtsrdhOXowQ%2F6pt1VLF8g51AjRtRJprjnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;247&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;743&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;br /&gt;현재는 대규모의 서비스도 아니고, 데이터를 여러번 가져오는 것만 개선하면 되기에 SWR을 사용해도 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 서비스가 커질 수 있다는 점, 그리고 스타트업과 IT 대기업 둘 다 react-query를 경험 해보았기에 실무에 초점이 더욱 맞춰져 있는 React Query를 도입했다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #006dd7; text-align: start;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;React Query&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를 도입하면, 쉽게 데이터를 가져올 수 있고 동일한 요청을 하는 여러 컴포넌트가 동시에 렌더링 되더라도 한 번만 요청한다. 또한, 백그라운드에서 서버에 주기적으로 polling을 하면서 데이터가 유효한지 검사하고, 유효하지 않으면 업데이트하여 데이터를 동기화하는 장점이 있다. 위에서 언급했던 코드의 복잡성과 길이를 최소화 할 수 있을 것이라고 생각했다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;그래서 어떻게 적용하는건데?&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react query를 사용하기 위해서는, 가장 최상위 index.tsx 파일에서 서비스 전체를 queryClientProvider로 감싸줘야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691982206937&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

root.render(
      &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
          &amp;lt;App /&amp;gt;
      &amp;lt;/QueryClientProvider&amp;gt;
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QueryClient &lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;인스턴스를 생성하고,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;QueryClientProvider&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;를 통해 서비스 전체에서 생성한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;QueryClient&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;에 접근 가능하도록 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이&lt;span&gt;&amp;nbsp;&lt;/span&gt;QueryClient는 단순하게 표현하자면&lt;span&gt;&amp;nbsp;&lt;/span&gt;QueryCache와&lt;span&gt;&amp;nbsp;&lt;/span&gt;MutationCache를 담는 그릇이다. 우리는 대부분의 경우에 직접&lt;span&gt;&amp;nbsp;&lt;/span&gt;QueryCache에 접근하기보다,&lt;span&gt;&amp;nbsp;&lt;/span&gt;QueryClient를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;QueryCache와&lt;span&gt;&amp;nbsp;&lt;/span&gt;MutationCache에 접근한다.&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceNUPV/btsak9GTTBJ/kayd2JfAISPXslo0C568U1/img.jpg&quot; data-lightbox=&quot;lightbox&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_95C85CAF3F0D-1.jpeg&quot; data-origin-width=&quot;1319&quot; data-origin-height=&quot;999&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cM3MNl/btsrcrjeznJ/xgFXh0d21T6VdjXmEpaXdk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cM3MNl/btsrcrjeznJ/xgFXh0d21T6VdjXmEpaXdk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cM3MNl/btsrcrjeznJ/xgFXh0d21T6VdjXmEpaXdk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcM3MNl%2FbtsrcrjeznJ%2FxgFXh0d21T6VdjXmEpaXdk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;282&quot; height=&quot;214&quot; data-filename=&quot;IMG_95C85CAF3F0D-1.jpeg&quot; data-origin-width=&quot;1319&quot; data-origin-height=&quot;999&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;QueryClientProvider를 통해 내려준&lt;span&gt;&amp;nbsp;&lt;/span&gt;queryClient에 접근하기 위해서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;useQueryClient를 사용한다.&lt;/p&gt;
&lt;p style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;QueryClient&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;는 직관적으로 표현하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;QueryCache&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;MutationCache&lt;/b&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;&lt;b&gt;를 담는 공간&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;서비스를 개발하면서 대부분의 경우에 직접&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;QueryCache&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;에 접근하기보다,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;QueryClient&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;를 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;QueryCache&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;MutationCache&lt;span style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;에 접근한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-family: 'Noto Sans Light'; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;QueryClientProvider를 통해 내려준&lt;span&gt;&amp;nbsp;&lt;/span&gt;queryClient에 접근하기 위해서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;useQueryClient를 사용하는 것이다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;background-color: #ffffff; color: #666666; text-align: left;&quot;&gt;&lt;code&gt;const queryClient = useQueryClient();&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 id=&quot;code-classlanguage-textusequerycode로-서버-데이터-가져오기&quot; style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://react-query.tanstack.com/reference/useQuery&quot;&gt;useQuery&lt;/a&gt;로 서버 데이터 가져오기&lt;/h3&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서버에서 데이터를 가져오고 캐싱을 하는데 사용하는 기본이며 가장 많이 사용하게 되는 훅이다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-language=&quot;jsx&quot;&gt;
&lt;pre class=&quot;reasonml&quot; style=&quot;background-color: #f5f2f0; color: #000000; text-align: left;&quot;&gt;&lt;code&gt;const { data, isLoading } = useQuery(queryKey, queryFunction, options)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;useQuery&lt;/span&gt;&lt;span style=&quot;color: #2e2e2e; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;의 첫 번째 인자는 Query Key로, Query Key를 하나만 넣을 수도 있지만 리스트로 여러 개를 넣을 수도 있다. &lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;쿼리 키가 가지는 유연함이 곧 캐싱을 처리를 쉽게 만들어준다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;두 번째 인자는 네트워크 요청을 하는 클로저를 넣어주면 된다. Promise 타입의 메서드를 넣어주면 된다.&lt;/span&gt; &lt;/span&gt;서버에서 데이터를 요청하고 Promise를 리턴하는 함수를 전달한다. 즉&lt;span&gt;&amp;nbsp;&lt;/span&gt;axios.get(...),&lt;span&gt;&amp;nbsp;&lt;/span&gt;fetch(...)&lt;span&gt;&amp;nbsp;&lt;/span&gt;등을 리턴하는 함수.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;마지막은 옵션을 넣을 수 있다. 여기서도 상당히 많은 옵션이 있는데, 주로 onSuccess나 onError을 통해 핸들러를 넣어줄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;span&gt; room이&lt;/span&gt;라는 키는 아래와 같이 확장할 수 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-language=&quot;jsx&quot;&gt;
&lt;pre class=&quot;typescript&quot; style=&quot;background-color: #f5f2f0; color: #000000; text-align: left;&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 다른 키로 취급한다. 
useQuery(['room', 1], ...)
useQuery(['room', 2], ...)

// 객체 필드의 값이 달라도 다른 키로 취급한다
useQuery(['room', { isAvailable: true }], ...)
useQuery(['room', { isAvailable: false }], ...)

// 객체 필드의 순서가 달라도 내용이 같으면 같은 키로 취급한다
useQuery(['room', { isAvailable: true, status: 'done' }], ...)
useQuery(['room', { status: 'done', isAvailable: true }], ...)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-language=&quot;jsx&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;useQuery 훅이 리턴하는 데이터와 옵션의 종류는 매우 다양하다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;공식 문서를 보면서 정리한 주요 사항은 다음과 같다. (자세한 내용은 공식&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://react-query.tanstack.com/reference/useQuery&quot;&gt;문서&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;참조)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Return Data&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;data&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 쿼리 함수가 리턴한 Promise에서 resolve된 데이터&lt;/li&gt;
&lt;li&gt;isLoading&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 저장된 캐시가 없는 상태에서 데이터를 요청중일 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;true&lt;/li&gt;
&lt;li&gt;isFetching&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 캐시가 있거나 없거나 데이터가 요청중일 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;true&lt;/li&gt;
&lt;li&gt;isError - API 요청이 실패했을 때 true&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Option&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cacheTime&lt;span&gt;&amp;nbsp;&lt;/span&gt;- unused 또는 inactive 캐시 데이터가 메모리에서 유지될 시간. 기본값은 5분이며 설정한 시간을 초과하면 메모리에서 제거된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Infinity로 설정하면 쿼리 데이터는 캐시에서 제거되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;staleTime&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 쿼리 데이터가 fresh 에서 stale로 전환되는데 걸리는 시간. 기본값은&lt;span&gt;&amp;nbsp;&lt;/span&gt;0이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Infinity로 설정하면 쿼리 데이터는 직접 캐시를 무효화할 때까지 fresh 상태로 유지된다.&lt;/li&gt;
&lt;li&gt;캐시는 메모리에서 관리되므로 브라우저 새로고침 후에는 다시 가져온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;enabled &lt;span&gt;&amp;nbsp;&lt;/span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;false&lt;span&gt;&amp;nbsp;&lt;/span&gt;값이 전달되면 쿼리가 비활성화된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 요청에 사용할 파라미터가 유효한 값일 때만 true를 할당하는 식으로 활용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;onSuccess&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 쿼리 함수가 성공적으로 데이터를 가져왔을 때 호출되는 함수.&lt;/li&gt;
&lt;li&gt;onError&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 쿼리 함수에서 오류가 발생했을 때&lt;/li&gt;
&lt;li&gt;onSettled&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 쿼리 함수의 성공, 실패 두 경우 모두 실행된다.&lt;/li&gt;
&lt;li&gt;keepPreviousData&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 쿼리 키(ex.페이지 번호)가 변경되어서 새로운 데이터를 요청하는 동안에도 마지막&lt;span&gt;&amp;nbsp;&lt;/span&gt;data값을 유지한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;페이지네이션을 구현할 때 유용하다. 캐시되지 않은 페이지를 가져올 때 화면에서 목록이 사라지는 깜빡임 현상을 방지할 수 있다.&lt;/li&gt;
&lt;li&gt;isPreviousData&lt;span&gt;&amp;nbsp;&lt;/span&gt;값으로 현재의 쿼리 키에 해당하는 값인지 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;initialData&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 캐시된 데이터가 없을 때 표시할 초기값.&lt;span&gt;&amp;nbsp;&lt;/span&gt;placeholder로 전달한 데이터와 달리 캐싱이 된다. 브라우저 로컬 스토리지에 저장해 둔 값으로 데이터를 초기화할 때 사용할 수 있을 것이다.&lt;/li&gt;
&lt;li&gt;refetchOnWindowFocus &amp;nbsp;- 윈도우가 다시 포커스되었을 때 데이터를 호출할 것인지 여부. 기본값은&lt;span&gt;&amp;nbsp;&lt;/span&gt;true이므로 필요없다고 판단되면 끄면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;그래서 코드는 어떻게 작성하는지?&lt;/b&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;UseQuery&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유지보수에 용이하도록 react query 코드, API 요청 코드, 키 값 파일로 분리해서 관리했다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691985529000&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// src/queries/room/useGetRoomInfo.ts

import { useQuery } from '@tanstack/react-query';
import { getRoomInfo } from '../../api/room';
import { QUERY_KEYS } from '../../constants/QUERY_KEYS';

export const useGetRoomInfo = (roomUUID: string) =&amp;gt; {
  return useQuery([QUERY_KEYS.ROOM.GET_ROOM_INFO, roomUUID], () =&amp;gt;
    getRoomInfo(roomUUID)
  );
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react query의 사용법은 어렵지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 말했듯이 &lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;서버에서 데이터를 가져오는(C&quot;&lt;/span&gt;&lt;span style=&quot;color: #2e2e2e; text-align: start;&quot;&gt;&lt;b&gt;R&quot;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot;&gt;UD의 R이라고 생각하면 편하다) 코드는 useQuery를 사용하면 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691986039616&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export const QUERY_KEYS = {
  ROOM: {
    GET_ROOM_INFO: 'get-room-info',
  },
  ...
  ...

};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리에 필요한 KEY들도 별도의 파일로 관리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키가 중복되는 경우가 없도록 작성하려고 해도 실수하는 &lt;u&gt;&lt;b&gt;&lt;i&gt;human error&lt;/i&gt; &lt;/b&gt;&lt;/u&gt;를 방지하고자 했다.&lt;/p&gt;
&lt;pre id=&quot;code_1691985708190&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// api/room.ts

import { instance } from './instance';
import { PostRoomTypes } from '../types/roomInfo';

export const getRoomInfo = async (roomUUID: string) =&amp;gt; {
  const { data } = await instance.get(`/api/room/${roomUUID}`);

  return data;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API를 요청하는 부분도 페이지별로 관리해서 유지보수에 용이하도록 했다.&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-language=&quot;jsx&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-language=&quot;jsx&quot;&gt;실제로 사용하는 컴포넌트 내부에서는 다음과 같이 사용하면 된다.&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #2e2e2e; text-align: start;&quot; data-language=&quot;jsx&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;적용 전&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1691980397461&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; useEffect(() =&amp;gt; {
    const getRoomInfo = async () =&amp;gt; {
      const { data } = await API.get(`/api/room/${roomUUID}`);
      setRoom(data);
    };
    getRoomInfo();
  }, []);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;적용 후&lt;/b&gt;&lt;/u&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1691980448381&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; const { data } = useGetRoomInfo(roomUUID);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드의 줄 수가 확연히 줄었고, 가독성이 좋아졌음을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;
&lt;h2 id=&quot;1192&quot; style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;useMutation&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p id=&quot;48f9&quot; style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;Query가 데이터를 Fetching하는 것에 비해, Mutation은 데이터를 생성, 변경, 삭제시킬 때 사용한다. 흔히 POST 요청이 포함된다.&lt;br /&gt;CRUD에서 R을 뺀 CUD 작업을 처리한다고 생각하면 편하다.&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;위와 마찬가지로 useCreateRoom.ts Hook 파일을 작성했다.&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691995884361&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// src/queries/room/useCreateRoom.ts

import { useMutation } from '@tanstack/react-query';
import { createRoom } from '../../api/room';
import { PostRoomTypes } from '../../types/roomInfo';

export const useCreateRoom = () =&amp;gt; {
  return useMutation((payload: PostRoomTypes) =&amp;gt; createRoom(payload));
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;useMutation&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;Hook에 실행하고자하는 Promise 타입의 메서드를 넣어주면 된다. 물론 옵션 같은건 추가할 수 있고,&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;useQuery&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;에 있는 Query Key는 딱히 넣어주지 않아도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #242424; text-align: start;&quot;&gt;키 값은 별도로 설정하지 않아도 되고 컴포넌트에서의 사용법은 다음과 같다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;background-color: #f9f9f9; color: #242424;&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const { mutate, data, isError, isSuccess } = useCreateRoom();

useEffect(() =&amp;gt; {
    if (
      '모든값이 입력 되었을 때' == true
    ) {
      mutate(room);

      if (isError) {
        confirm('오류가 발생했습니다.\n처음부터 다시 시도하세요');
        navigate(`${ROUTES.LANDING}`);
      }

      if (isSuccess) {
        navigate(`${ROUTES.CURRENT}/${data.roomUuid}`);
      }
    }
  }, [room, isError, isSuccess]);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;실질적인 동작은 mutate를 호출해서 진행한다.&lt;br /&gt;isError와 isSuccess 값을 활용하여서 API 호출을 실패했을 때와 성공했을 때를 구분하여 로직을 구현할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;
&lt;p id=&quot;934b&quot; style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;Mutation 자체에 대한 것은 특별할 것이 별로 없으나, Query Key를 잘 활용해 Query를 Invalidation하거나 데이터를 업데이트하는 상황에서 적절히 사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;react query를 도입한 덕분에 코드의 수가 확연히 줄었고 가독성이 크게 좋아졌다.&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;이후 react query의 장점을 살려 서버의 요청 수를 줄이고, 캐싱 데이터를 활용한 예시는&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;추후 별도의 포스팅으로 작성할 예정이다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;ca81&quot; style=&quot;color: #242424;&quot; data-selectable-paragraph=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>대외활동/DND 8기</category>
      <category>React Query</category>
      <category>useMutation</category>
      <category>useQuery</category>
      <category>리액트 쿼리</category>
      <category>모두의시간</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/58</guid>
      <comments>https://yeshyun.tistory.com/58#entry58comment</comments>
      <pubDate>Mon, 14 Aug 2023 16:06:02 +0900</pubDate>
    </item>
    <item>
      <title>iOS 15 대응 - 사파리 가상키보드 이슈 (feat. 크로스 브라우징)</title>
      <link>https://yeshyun.tistory.com/57</link>
      <description>&lt;p&gt;모두의 시간 서비스 QA 과정을 거치면서 발견한 크로스 브라우징 문제를 해결했던 경험을 작성한다.&lt;/p&gt;
&lt;p&gt;iOS15 버전이 릴리즈 된 이후에 사파리 브라우저에서만 발생하는 &amp;#39;크로스브라우징&amp;#39; 이슈인 만큼 자세히 기록하고자 한다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;1. 이슈 발생&lt;/strong&gt;&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_8575.PNG&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;2436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brBxb5/btspHZwpN8h/wIsQfmLuSHWXNkIdR1kx6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brBxb5/btspHZwpN8h/wIsQfmLuSHWXNkIdR1kx6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brBxb5/btspHZwpN8h/wIsQfmLuSHWXNkIdR1kx6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrBxb5%2FbtspHZwpN8h%2FwIsQfmLuSHWXNkIdR1kx6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;272&quot; height=&quot;589&quot; data-filename=&quot;IMG_8575.PNG&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;2436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;모두의시간 서비스에서 방을 생성하는 과정에서 input창에 정보를 입력해야 되는 부분이 있다.&lt;/p&gt;
&lt;p&gt;input 창을 클릭하면 하단에서 키보드가 올라오는데, &lt;strong&gt;키보드 창이 올라온 상황에서 스크롤을 아래로 내리면 검은 빈공간이 표시&lt;/strong&gt;된다.&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        

&lt;p&gt;서비스 사용에는 문제가 없지만, 사용자의 경험을 헤칠 수 있는 문제가 있기에 이를 해결하고자 했다.&lt;/p&gt;
&lt;p&gt;파악한 이슈는 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;키보드를 열기전 : 화면의 높이&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;키보드를 열었을 때 : 화면의 높이 + 키보드의 높이&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;키보드가 나오기 전에는 document가 존재할 수 있는 영역은 화면의 높이 만큼이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;하지만 사용자가 정보를 입력하기 위해 Input 창을 클릭하면, 키보드가 올라오고 document를 키보드 높이만큼 그대로 밀어 올린다. 동시에 키보드 뒤쪽에는 가상의 영역이 생성된다.&lt;/p&gt;
&lt;p&gt;일반적으로 페이지에 손가락을 대고 움직이면 화면이 스크롤 된다. 이는 정확히는 html태그가 스크롤 된다고 생각하면 된다.&lt;/p&gt;
&lt;p&gt;iOS 운영체제는 사파리 운영체제에서 키보드 창을 열었을 때 키보드 뒤쪽에 가상의 영역을 생성한다. 그래서 키보드가 열린 상태에서 스크롤을 하게되면 html태그가 먼저 스크롤 되는 것이 아니라, 먼저 document가 키보드 뒤쪽의 가상영역으로 스크롤 되는 것이다. 스크롤이 되다가 document가 키보드 뒤쪽의 가상영역의 하단에 닿게 되면 그때부터 내부의 html태그가 스크롤 된다.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2. 어떻게 해결했나?&lt;/strong&gt;&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;그래서 내가 생각했던 방법은 2가지가 있었다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;페이지의 높이가 screen의 높이(height: 100%)로 고정이 되어있고 내부에서 스크롤 되도록 하는 방식&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;키보드가 활성화 된 상태에서 스크롤 이벤트가 발생하면 blur 처리로 키보드를 비활성화 시키는 방식&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;1번과 2번 중에 고민을 했는데, &lt;strong&gt;1번의 장점은 키보드가 올라온 상태에서도 스크롤이 가능하다는 것&lt;/strong&gt;이었다.&lt;/p&gt;
&lt;p&gt;하지만 현재 입력하고 있는 Input 창에서 다른 곳으로 스크롤을 하는 것이 불필요하다고 생각했다. 정보를 입력할 때 하단이나 상단의 정보를 참고하면서 작성해야 되는 경우이면 1번으로 진행했겠지만, 오히려 다른 곳을 클릭했을 때, 혹은 스크롤을 할 때 키보드 또한 비활성화 하는 게 사용경험이 높을 것이라고 생각했다.&lt;/p&gt;
&lt;p&gt;그래서 &lt;strong&gt;스크롤을 할 때 키보드를 비활성화 할 수 있다는 장점이 있는 2번&lt;/strong&gt;을 선택했다.&lt;/p&gt;
&lt;p&gt;2번의 단점은 키보드가 활성화 된 상태에서 스크롤이 불가능하다는 것인데, 현재 모두의시간 서비스에서는 불필요하기에 2번으로 진행했다.&lt;/p&gt;
&lt;p&gt;처음 간단하게 생각했던 개발방향의 큰 그림은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1) Input창이 활성화(focus) 된 것을 인지&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2) 활성화 된 상태에서 스크롤(scroll) 이벤트 발생 인지&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3) Input창 비활성화&lt;/strong&gt;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        

&lt;p&gt;처음 작성한 코드는 아래와 같다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const useInputScroll = (ref: React.RefObject&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
  useEffect(() =&amp;gt; {
    window.addEventListener(&amp;#39;scroll&amp;#39;, handleScroll);
    return () =&amp;gt; {
      window.removeEventListener(&amp;#39;scroll&amp;#39;, handleScroll);
    };
  }, []);

  const handleScroll = (e: { target: any }) =&amp;gt; {
    if (
      document.activeElement == ref.current ||
      ref.current?.contains(e.target)
    ) {
      (document.activeElement as HTMLElement).blur();
    }
  };
};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;activeElement를 사용해 input 태그가 focus 되어있는 것을 판별해 blur 처리 하였다.&lt;/p&gt;
&lt;p&gt;금방 해결할 수 있겠다고 생각한 것도 잠시...&lt;/p&gt;
&lt;p&gt;처음 기획한 방향으로 구현을 해보니, 키보드가 올라올 때 발생하는 스크롤 이벤트도 인식을 해버렸다&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1) Input창이 활성화(focus) 된 것을 인지&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2) 활성화 된 상태에서 스크롤(scroll) 이벤트 발생 인지&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3) Input창 비활성&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;사용자가 Input 창을 클릭하는 순간 1번과 2번이 동시에 실행&lt;/strong&gt;되어, 곧바로 Input 창이 비활성화 되는 문제가 발생했다.&lt;/p&gt;
&lt;p&gt;그래서 scroll 이벤트가 아닌 &amp;#39;click&amp;#39; 이벤트로 변경해보았지만, click 이벤트는 터치를 할 때 발생하는 이벤트였다.&lt;/p&gt;
&lt;p&gt;데스크탑으로 따지면 마우스를 &amp;#39;&lt;strong&gt;클&lt;/strong&gt;&amp;#39;릭하는 순간이 아니라 &amp;#39;&lt;strong&gt;클릭&lt;/strong&gt;&amp;#39; 하는 순간, 즉 손을 떼는 순간에 발생하는 이벤트여서&lt;/p&gt;
&lt;p&gt;Input 창을 클릭하는 순간 위와 같은 문제인 1번과 2번이 동시에 인식되어 키보드가 곧바로 사라졌다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDx6kb/btspZDZIT1f/oD1S0oLwWpXJQkKkG7IYk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDx6kb/btspZDZIT1f/oD1S0oLwWpXJQkKkG7IYk0/img.png&quot; data-alt=&quot;참조:&amp;amp;amp;nbsp; https://ui.toast.com/posts/ko_20220106&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDx6kb/btspZDZIT1f/oD1S0oLwWpXJQkKkG7IYk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDx6kb%2FbtspZDZIT1f%2FoD1S0oLwWpXJQkKkG7IYk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;691&quot; height=&quot;424&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;참조:&amp;amp;nbsp; https://ui.toast.com/posts/ko_20220106&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;그래서 &lt;strong&gt;모바일 기기에서의 터치 이벤트에 대해 자세히 학습했다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;다음으로 든 생각은 그럼 input 창이 활성화된 상태에서 click 이벤트가 발생되면 키보드를 비활성화 시켜야겠다고 생각했는데&lt;/p&gt;
&lt;p&gt;모바일 환경에서 스크롤을 할 때는 터치를 한 상태에서 손가락을 움직이기에 한템포 늦게 실행되었다.&lt;/p&gt;
&lt;p&gt;모바일 환경에서는 touchstart -&amp;gt; touchmove -&amp;gt; touchend 발생한다는 것을 알게되었고&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;touchmove**&lt;/strong&gt;(터치한 상태로 움직이는 행위)를 인식하는 방향으로 수정했다.**&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;3. 최종 수정사항&lt;/strong&gt;&lt;/h3&gt;
&lt;hr&gt;
&lt;pre&gt;&lt;code&gt;import React, { useEffect } from &amp;#39;react&amp;#39;;

const useInputScroll = (ref: React.RefObject&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
  useEffect(() =&amp;gt; {
    window.addEventListener(&amp;#39;touchmove&amp;#39;, handleScroll);
    return () =&amp;gt; {
      window.removeEventListener(&amp;#39;touchmove&amp;#39;, handleScroll);
    };
  }, []);

  const handleScroll = (e: { target: any }) =&amp;gt; {
    if (
      document.activeElement == ref.current ||
      ref.current?.contains(e.target)
    ) {
      (document.activeElement as HTMLElement).blur();
    }
  };
};

export default useInputScroll;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;리액트에서 ref를 설정할 수 있는 useRef를 이용하여, Input 태그에 적용하고 훅으로 넘기는 코드를 작성했다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;touchmove&lt;/strong&gt; 이벤트가 감지되면 handleScroll 함수가 실행되고,&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;document.activeElement&lt;/strong&gt;를 통해 현재 전달받은 &lt;strong&gt;ref가 focus 되어있는지 판별&lt;/strong&gt;했다.&lt;/p&gt;
&lt;p&gt;focus 되어있는 상황에서 touchmove 이벤트가 감지되면&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;document.activeElement.blur() 이벤트를 호출하여 focus를 unfocus 되도록&lt;/strong&gt; 하는 코드이다.&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        

&lt;p&gt;영상을 보면 해결하고자 했던 방향대로 잘 수정되었다.&lt;/p&gt;
&lt;p&gt;방생성 페이지와 마찬가지로 로그인 페이지에서도 같은 오류가 있어서 Hook으로 작성했다.&lt;/p&gt;
&lt;p&gt;이슈를 해결하면서 크로스 브라우징 문제는 언제 어디서나 존재할 수 있으니, 꼼꼼한 QA가 필수라는 것을 깨달았고 focus, blur, input, 마우스 핸들링 이벤트 등에 대해 학습할 수 있었다.&lt;/p&gt;
&lt;p&gt;크로스 브라우징 이슈를 1순위로 생각하며, 어떠한 브라우저와 핸드폰으로 접속하여도 같은 경험을 제공하는 것이 우선이라는 생각이 들었다. 또한 지속적으로 모니터링 하면서, 조금이라도 사용경험을 개선할 수 있는 것은 계속해서 수정할 예정이다.&lt;/p&gt;</description>
      <category>대외활동/DND 8기</category>
      <category>active blur</category>
      <category>activeElement</category>
      <category>Blur</category>
      <category>ios 크로스브라우징</category>
      <category>touchmove 이벤트</category>
      <category>리액트 가상키보드</category>
      <category>모두의시간</category>
      <category>사파리 가상키보드</category>
      <category>자바스</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/57</guid>
      <comments>https://yeshyun.tistory.com/57#entry57comment</comments>
      <pubDate>Thu, 3 Aug 2023 16:06:59 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 변수 호이스팅에 대하여 (var, let 차이점)</title>
      <link>https://yeshyun.tistory.com/56</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. var&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var 키워드가 호이스팅이 된다는 것은 이해했지만, &lt;a href=&quot;https://yeshyun.tistory.com/50&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(이전 작성했던 글)&lt;/a&gt;&lt;br /&gt;let과 const 키워드도 호이스팅이 된다는 것을 완전히 이해하지는 못했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 헷갈렸던 이론을 탐구해보고자 글을 작성한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var 키워드로 변수를 선언하면 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 변수 호이스팅에 의해 var 키워드로 선언한 변수는 변수 선언문 이전에 참조가 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1691029512243&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.log(abc); // undefined

abc = '123';

console.log(abc); // 123

var abc;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 할당문 이전에 변수를 참조하면 언제나 undefined를 반환하는 것에 유의해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 변수 선언문 이전에 변수를 참조하는 것은 가독성을 떨어트리고 오류를 발생시킬 여지가 충분하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. let&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES6 이후에 var 키워드의 단점을 보완하기 위해 let과 const를 도입했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let의 특징은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) 변수 중복 선언 금지&lt;/b&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1691030041101&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var a = 123;

var a = 456;

let c = 123;

let c = 456; // SyntaxError&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) 블록 레벨 스코프&lt;/b&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1691030105851&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let a = 1;

{
  let a = 2;
  let b = 3;
}

console.log(a); // 1
console.log(b); // ReferenceError&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수의 코드 블록만을 지역스코프로 인정하는 함수 레벨 스코프 var 키워드와는 달리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let 키워드로 선언한 변수는 모든 크도블록을 지역스코프로 인정하는 블록 레벨 스코프를 따른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 위 예제의 코드 블록 내에서 선언된 &lt;b&gt;a 변수와 b 변수는 지역변수&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역에서 선언된 a 변수와 코드 블록 내의 a 변수는 서로 다른 변수이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 &lt;b&gt;b 변수도 지역변수이므로 전역에서 b 변수를 참조할 수 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3) 호이스팅&lt;/b&gt;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let 키워드로 선언한 변수는 호이스팅이 발생하지 않는 것처럼 동작한다.&lt;/p&gt;
&lt;pre id=&quot;code_1691030388702&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.log(a); // ReferenceError
let a;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 let 키워드로 선언한 변수를 선언문 이전에 참조하면 참조에러(ReferenceError)가 발생한다.&lt;/p&gt;
&lt;pre id=&quot;code_1691030538518&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.log(a); // undefined

var a;
console.log(a); // undefined

a = 1;
console.log(a); // 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 선언에서 살펴본 바와 같이 var 키워드로 선언한 변수는 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; '선언단계'와 '초기화 단계'가 한 번에 진행된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 변수 선언문 이전에 변수에 접근해도 에러가 발생하지 않고 &lt;b&gt;undefined를 반환&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMLLgj/btspNQTzrSC/mcqHKyy7khFCTLNcOBEjC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMLLgj/btspNQTzrSC/mcqHKyy7khFCTLNcOBEjC0/img.png&quot; data-alt=&quot;var 키워드 생명주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMLLgj/btspNQTzrSC/mcqHKyy7khFCTLNcOBEjC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMLLgj%2FbtspNQTzrSC%2FmcqHKyy7khFCTLNcOBEjC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;142&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;var 키워드 생명주기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&lt;b&gt; let 키워드로 선언한 변수는 '선언단계'와 '초기화단계'가 분리되어 진행&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계가 먼저 실행되지만,&lt;b&gt; 초기화 단계는 변수 선언문에 도달했을 때 실행&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;let 키워드로 선언한 변수는 스코프의 시작 지점부터 변수 선언문까지(초기화 단계 시작 지점) 변수를 참조할 수 없다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;'일시적 사각지대(TDZ)'&lt;/b&gt;&lt;/span&gt;라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691030747315&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.log(a); // ReferenceError

let a;
console.log(a); // undefined

a = 1;
console.log(a); // 1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAvHi/btspO96o98E/XP1Bug5L0pHRQc9OFDDWVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAvHi/btspO96o98E/XP1Bug5L0pHRQc9OFDDWVK/img.png&quot; data-alt=&quot;let 키워드 생명주기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAvHi/btspO96o98E/XP1Bug5L0pHRQc9OFDDWVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAvHi%2FbtspO96o98E%2FXP1Bug5L0pHRQc9OFDDWVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;657&quot; height=&quot;251&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;let 키워드 생명주기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 보인다.&lt;span style=&quot;color: #1a5490;&quot;&gt;&lt;b&gt; 하지만 그렇지 않다 (중요!)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691030877164&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let a = 1;

{
  console.log(a); // ReferenceError
  let a = 2;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 호이스팅이 발생하지 않았다면, 전역 변수인 a의 값인 1을 출력했어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 let 키워드로 선언한 변수도 여전히 호이스팅이 발생하기 때문에 참조 에러(ReferenceError)가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트는 ES6에서 도입된 let, const를 포함해서 모든 선언(var, let, const, function, class 등)을 호이스팅한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, ES6에서 도입된 let, const, class를 사용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;모던자바스크립트.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ze80g/btspRhXiVVi/Picjtn5s16UEvgPa8Xh9TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ze80g/btspRhXiVVi/Picjtn5s16UEvgPa8Xh9TK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ze80g/btspRhXiVVi/Picjtn5s16UEvgPa8Xh9TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fze80g%2FbtspRhXiVVi%2FPicjtn5s16UEvgPa8Xh9TK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;395&quot; height=&quot;541&quot; data-filename=&quot;모던자바스크립트.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;해당&amp;nbsp;&lt;/span&gt;글은&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&amp;nbsp;[&lt;/span&gt;모던 자바스크립트&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&amp;nbsp;Deep Dive - 저자 이응모] 도서의 내용을 참고했습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <category>let 호이스팅</category>
      <category>var 호이스팅</category>
      <category>자바스크립트 TDZ</category>
      <category>자바스크립트 변수 호이스팅</category>
      <category>자바스크립트 호이스팅</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/56</guid>
      <comments>https://yeshyun.tistory.com/56#entry56comment</comments>
      <pubDate>Thu, 3 Aug 2023 11:57:50 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 스코프 체인, 렉시컬 스코프, 중첩함수에 대하여</title>
      <link>https://yeshyun.tistory.com/55</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 중첩함수와 외부함수&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수는 전역에서 정의할 수도 있고, 내부에서 정의할 수도 있다. 함수 몸체 내부에서 함수가 정의된 것을 '함수의 중첩'이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 함수 몸체 내부에서 정의한 함수를 &lt;b&gt;'중첩함수(nested function)'&lt;/b&gt;&lt;br /&gt;중첩함수를 포함하는 함수를 &lt;b&gt;'외부함수(outer function)'&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수는 중첩될 수 있으므로, 지역 스코프도 중첩될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 스코프가 함수의 중첩에 의해 계층적 구조를 갖는다는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말해 중첩 함수의 지역 스코프는 중첩 함수를 포함하는 외부 함수의 지역 스코프와 &lt;b&gt;계층적 구조&lt;/b&gt;를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이때 외부 함수의 지역 스코프를 중첩 함수의 상위 스코프라 한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1690939879788&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 전역 스코프
var x = 'global x'
var y = 'global y'

// 지역 스코프(outer)
function outer(){
  var z = 'outer z';

  // 지역 스코프(inner)
  function inner(){
    var x = 'inner x';

    console.log(x); // 1)
    console.log(y); // 2)
    console.log(z); // 3)
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에서는 outer 함수의 지역과 inner 함수의 지역, 그리고 전역지역이 있다.&lt;br /&gt;이때 outer 함수가 만든 지역 스코프는 inner 함수가 만든 지역 스코프의 상위 스코프다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 outer 함수의 지역 스코프의 상위 스코프는 전역 스코프다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 스코프체인&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;1348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUtAmv/btspxbRFz9b/eoG1qWruaXq3uMIOLyYqvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUtAmv/btspxbRFz9b/eoG1qWruaXq3uMIOLyYqvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUtAmv/btspxbRFz9b/eoG1qWruaXq3uMIOLyYqvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUtAmv%2FbtspxbRFz9b%2FeoG1qWruaXq3uMIOLyYqvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;309&quot; height=&quot;611&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;1348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 모든 스코프는 하나의 계층적 구조로 연결되며, &lt;b&gt;모든 지역 스코프의 최상위 스코프는 전역 스코프다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;이렇게 스코프가 계층적으로 연결된 것을 '&lt;span style=&quot;color: #ee2323;&quot;&gt;스코프 체인&lt;/span&gt;'이라고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서는 전역 스코프, outer 함수의 지역 스코프, inner 함수의 지역 스코프로 이뤄진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수를 참조할 때는 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색(identifier resolution)한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 검색예시&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;1) x 변수를 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 x 변수가 선언되었는지 검색 -&amp;gt; inner 함수에 x 변수 존재함 -&amp;gt; 검색된 변수 참조&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;2) y 변수를 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 y 변수가 선언되었는지 검색 -&amp;gt; inner 함수에 y 변수 존재 X -&amp;gt; 상위 스코프인 outer 함수에서 검색 -&amp;gt; outer 함수에 y변수 존재 X -&amp;gt; 상위 스코프인 전역(global)스코프에서 검색 -&amp;gt; 전역 스코프에 y 변수 존재함 -&amp;gt; 검색된 변수 참조&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;3) z 변수를 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 z 변수가 선언되었는지 검색 -&amp;gt; inner 함수에 z 변수 존재 X -&amp;gt; 상위 스코프인 outer 함수에서 검색 -&amp;gt; outer 함수에 z변수 존재함 -&amp;gt; 검색된 변수 참조&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;절대 하위 스코프로 내려가면서 식별자를 검색하는 일은 없다.&lt;/b&gt; 이는 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만 &lt;b&gt;하위스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없다는 것을 의미한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 렉시컬 스코프&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690941356519&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var x = 1;

function foo() {
	var x = 10;
    bar();
}

function bar() {
	console.log(x);
}

foo(); // 1
bar(); // 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수의상위 스코프가 결정되는 패턴을 2가지로 예측할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 함수를 어디서 호출했는지에 따라 함수의 상위 스코프 결정 ( 동적 스코프 )&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 함수를 어디서 정의했는지에 따라 함수의 상위 스코프 결정 ( 렉시컬 스코프, 정적 스코프 )&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;동적스코프&lt;/b&gt;는 함수를 정의하는 시점에는 함수가 어디서 호출될지 알 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 함수가 호출되는 시점에 동적으로 상위 스코프를 결정해야 하기 때문에 동적 스코프라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정적 스코프&lt;span&gt; , 즉 렉시컬 스코프는 &lt;/span&gt;&lt;/b&gt;동적 스코프처럼 상위 스코프가 동적으로 변하지 않고 함수 정의가 평가되는 시점에 상위 스코프가 정해진다. 대부분의 언어를 비롯해 자바스크릅티는 렉시컬 스코프를 따른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 함수의 상위 스코프는 함수 정의가 실행될 때 정적으로 결정된다.&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <category>자바스크립트 렉시컬스코프</category>
      <category>자바스크립트 스코프 체인</category>
      <category>자바스크립트 중첩함수</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/55</guid>
      <comments>https://yeshyun.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 2 Aug 2023 11:00:47 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 객체 리터럴(프로퍼티, 생성자, 리터럴 확장)</title>
      <link>https://yeshyun.tistory.com/54</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 객체란?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트는 객체 기반의 프로그래밍 언어이며, 자바스크립트를 구성하는 거의 모든 것이 객체이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원시 값을 제외한 나머지 값(함수, 배열, 정규표현식 등)은 모두 객체다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;원시 값: 변경 불가능한 값&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;객체 값: 변경 가능한 값&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1690506180291&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var person = {
  name : 'Lee',
  age : 20
};

// 프로퍼티 키 : 프로퍼티 값&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 0개 이상의 프로퍼티로 구성된 집합이며, 프로퍼티는 키key와 값value으로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있고, 함수도 일급객체이므로 값으로 취급이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드method라 부른다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 객체는 프로퍼티와 메서드로 구성된 집합체이다.&lt;/p&gt;
&lt;pre id=&quot;code_1690506659841&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var counter = {
  num : 0,
  increase : function() { this.num++; }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티 : 객체의 상태를 나타내는 값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드 : 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 객체 리터럴에 의한 객체 생성&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 기반의 객체지향 언어인 C++과 자바와 같은 언어와 달리, 자바스크립트는 프로토타입 기반의 객체지향 언어이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;객체 리터럴&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Object 생성자 함수&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;생성자 함수&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Object.create 메서드&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;클래스(ES6)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음처럼 다양한 객체 생성 방법을 지원하고 가장 일반적이고 간단한 방법은 '객체 리터럴'을 사용하는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1690507736077&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var person = {
  name: 'Lee',
  sayHello: function() {
    console.log(`Hello this is ${this.name}`);
  }
};

console.log( typeof person ) // object&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 리터럴의 중괄호는 코드 블록을 의미하지 않는 것에 주의해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 리터럴은 값으로 평가되는 표현식이다. 따라서 객체 리터럴의 닫는 중괄호 뒤에는 세미콜론을 붙인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 프로퍼티&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다.&lt;/p&gt;
&lt;pre id=&quot;code_1690508598821&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var person = {
  name: 'Lee',
  age: 20
};&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심벌 값&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티 키는 프로퍼티 값에 접근할 수 있는 이름으로서 식별자 역할을 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 반드시 식별자 네이밍 규칙을 따라야 하는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 식별자 네이밍 규칙을 준수하는 프로퍼티 키와 그렇지 않은 프로퍼티 키는 미묘한 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티 키는 문자열이므로 따옴표로 묶어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 네이밍 규칙을 준수하는 이름은 따옴표를 생략할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1690508854522&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var person = {
  firstName: 'Hyun',
  'last-name': 'Roh'
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, 식별자 네이밍 규칙을 따르지 않는 이름에는 반드시 따옴표를 사용해야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 프로퍼티 접근&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티에 접근하는 방법은 2가지가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;마침표 프로퍼티 접근 연산자(.)를 사용하는 마침표 표기법&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대괄포 프로퍼티 접근 연산자([...])를 사용하는 대괄호 표기법&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1690509260982&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var person = {
  name: 'Lee'
}

console.log(person.name) // Lee
console.log(person['name']) // Lee&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의해야할 점은 대괄호 표기법을 사용하는 경우에는 반드시 '따옴표'로 감싼 문자열이어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. ES6에서 추가된 객체 리터럴의 확장 기능&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1690510082414&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ES5
var x = 1, y = 2;

var obj = {
  x: x,
  y: y
};

console.log(obj) // {x: 1, y: 2}

// ES6
let x = 1, y = 2

const obj = { x, y };

console.log(obj); // {x: 1, y: 2}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES6에서는 프로퍼티 값으로 변수를 사용하는 경우 변수 이름과 프로퍼티 키가 동일한 이름일 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티 키를 생략할 수 있다. 이때 프로퍼티 키는 변수 이름으로 자동 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690510351118&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ES5
var obj = {
  name: 'Lee'
  sayHi: function() {
    console.log('Hi! ' + this.name);
  }
};

obj.sayHi(); // Hi! Lee

// ES6
const obj = {
  name: 'Lee',
  sayHi() {
    console.log('Hi! ' + this.name);
  }
};

obj.sayHi(); // Hi! Lee&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 기존 메서드를&amp;nbsp; 정의하려면 프로퍼티 값으로 함수를 할당해야 했던 ES5와는 달리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES6에서는 메서드를 정의할 때 function 키워드를 생략한 축약 표현을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;모던자바스크립트.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OE12v/btspdsZI2eb/YAjGIdHySiH2E3bY9EcnH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OE12v/btspdsZI2eb/YAjGIdHySiH2E3bY9EcnH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OE12v/btspdsZI2eb/YAjGIdHySiH2E3bY9EcnH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOE12v%2FbtspdsZI2eb%2FYAjGIdHySiH2E3bY9EcnH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;422&quot; height=&quot;578&quot; data-filename=&quot;모던자바스크립트.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;해당&amp;nbsp;&lt;/span&gt;글은&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&amp;nbsp;[&lt;/span&gt;모던 자바스크립트&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&amp;nbsp;Deep Dive - 저자 이응모] 도서의 내용을 정리한 글입니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <category>ES6</category>
      <category>객체</category>
      <category>자바스크립트</category>
      <category>자바스크립트 객체 리터럴</category>
      <category>자바스크립트 객체 생성</category>
      <category>자바스크립트 객체 생성자</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/54</guid>
      <comments>https://yeshyun.tistory.com/54#entry54comment</comments>
      <pubDate>Fri, 28 Jul 2023 11:16:29 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 타입 변환과 단축 평가 (옵셔널체이닝 연산자, null 병합 연산자, 논리 연산자)</title>
      <link>https://yeshyun.tistory.com/53</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이번 파트를 공부하면서, 스타트업 인턴 당시 서버에서 값을 불러오는 과정에서 사용했던 문법들을 보게되어&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;괜히 반갑고 이유를 알 수 있어서 부족한 점을 하나씩 채워나가는 기분이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: left;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 타입 변환이란?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트의 모든 값은 타입이 있다. 값의 타입은 개발자의 의도에 따라 다른 타입으로 변환할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;명시적 타입 변환(타입 캐스팅) :&lt;/b&gt; 개발자가 의도적으로 값의 타입을 변환하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;암묵적 타입 변환(타입 강제 변환)&lt;/b&gt; : 표현식을 평가하는 도중에 자바스크립트 엔진에 의해 암묵적으로 타입이 자동 변환되는 것&lt;/p&gt;
&lt;pre id=&quot;code_1690421452995&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var x = 10;

var str = x.toString(); // 명시적 타입변환
console.log(typeof str, str); // string 10

var str2 = x + ''; // 암묵적 타입변환
console.log(typeof str2, str2); // string 10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명시적 타입 변환이나 암묵적 타입 변환이 기족 원시 값을 직접 변경하는 것은 아니다. 원시 값은 변경 불가능한 값이므로 변경할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입 변환이란 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명시적 타입 변환은 타입을 변경하겠다는 개발자의 의지가 코드에 명백히 드러난다. 하지만 암묵적 타입 강제 변환은 자바스크립트 엔진에 의해 암묵적으로, 즉 드러나지 않게 타입이 자동 변환되기 때문에 타입을 변경하겠다는 개발자의 의지가 코드에 명백히 나타나지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 암묵적 타입 변환이 발생하는지, 만약 발생한다면 어떤 타입으로 변환되는지 예측 가능해야 한다. 예측하지 못한다면 오류를 생산할 가능성이 높아진다. 여기에서 더 중요한 것은 코드를 예측할 수 있게 작성해야 된다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동료가 작성한 코드를 정확히 이해할 수 있어야 하고 자신이 작성한 코드도 동료가 쉽게 이해할 수 있는 코드를 작성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 불리언 타입으로 변환&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;if 문이나 for 문과 같은 제어문 또는 삼항 조건 연산자의 조건식은 불리언 값, 즉 논리적 참/거짓으로 평가되어야 하는 표현식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 엔진은 조건식의 평과 결과를 불리언 타입으로 암묵적 타입 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 엔진은 불리언 타입이 아닌 값을 Truthy 값(참으로 평가되는 값) 또는 Falsy 값(거짓으로 평가되는 값)으로 구분한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fasly 값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- false&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- undefined&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- null&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 0, -0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- NaN&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ' '(빈 문자열)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Falsy 값 외의 모든 값은 모두 true로 평가되는 Truthy 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) Boolean 생성자 함수를 new 연산자 없이 호출하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423858627&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Boolean('x'); // true
Boolean(''); // false
Boolean('false'); // true&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2)&amp;nbsp; ' ! '&amp;nbsp; 부정 논리 연산자를 두 번 사용하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423915427&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;!!'x'; // true
!!''; // false
!!'false'; // true
!!0; // false
!!1 // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 문자열 타입으로 변환&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) String 생성자 함수를 new 연산자 없이 호출하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423490095&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var num = 10;
String(num) // &quot;10&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) Object.prototype.toString 메서드를 사용하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423515208&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var num = 10;
num.toString() // &quot;10&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3) 문자열 연결 연산자를 이용하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423540159&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var num = 10;
num + '' // '10'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 숫자 타입으로 변환&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) Number 생성자 함수를 new 연산자 없이 호출하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423633678&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var str = &quot;10&quot;
Number(str) // 10&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) parseInt, parseFloat 함수를 사용하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423676827&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var str = '10';
parseInt(str); // 10&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3) + 단항 산술 연산자를 이용하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423719426&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var str = '10';
+ str; // 10&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4) * 산술 연살자를 이용하는 방법&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1690423751444&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var str = '10';
str * 1; // 10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 단축평가&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1) 논리 연산자 ( &amp;amp;&amp;amp;, | | )&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리합( || ) 또는 논리곱( &amp;amp;&amp;amp; ) 연산자 표현식의 평가 결과는 불리언 값이 아닐 수도 있다. 논리합 또는 논리곱 연산자 표현식은 언제나 2개의 피연산자 중 어느 한쪽으로 평가된다는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1690424782112&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'Cat' &amp;amp;&amp;amp; 'Dog' // &quot;Dog&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리곱 연산자는 두 개의 피연산자가 모두 true일 때 true를 반환한다. 또한 논리곱 연산자는 좌항에서 우항으로 평가가 진행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 피연산자 'Cat'은 true로 평가된다. 하지만 이 시점까지는 표현식을 평가할 수 없고 두 번째 피연산자인 'Dog'까지 평가해 보아야 가능하다. 다시 말 해, 두 번째 피연산자가 위 논리곱 연산자 표현식의 평가 결과를 결정하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때&lt;b&gt; 논리곱 연산자는 논리 연산의 결과를 결정하는 두 번째 피연산자인 'Dog'를 그대로 반환한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690424930037&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'Cat' || 'Dog' // &quot;Cat&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리합 연산자는 두 개의 피연산자 중 하나만 true로 평가되어도 true를 반환한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 피연산자 'Cat'은 Truthy 값이므로 true로 평가된다. 이 시점에 두 번째 피연산자까지 평가해 보지 않아도 표현식 평가가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 &lt;b&gt;논리합 연산자는 표현식의 결과를 결정하는 첫 번째 피연산자 'Cat'을 그대로 반환한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이처럼 논리곱과 논리합 연산자는 논리 연산의 결과를 결정하는 피연사자를 타입 변환하지 않고 그대로 반환한다. 이를 단축평가라 한다. 단축 평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축 평가를 사용하면 if 문을 대체할 수 있다. 어떤 조건이 Truthy 값일 때 무언가를 해야 한다면 논리곱(&amp;amp;&amp;amp;) 연산자 표현식으로 if 문을 대체할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1690425722464&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var done = true;
var message = '';

if (done) message = '완료'

message = done &amp;amp;&amp;amp; '완료';
console.log(message) //완료&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2) 옵셔널 체이닝 연산자 ( ?. )&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES11(ECMAScript2020)에서 도입된 옵셔널 체이닝 연산자 ?.는&lt;b&gt; 좌항의 피연산자가 null 또는 undefined인 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;undefined를 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어간다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵셔널 체이닝 연산자 ?.는 객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때 유용하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에는 앞서 살펴본 논리연산자 &amp;amp;&amp;amp;를 사용한 단축 평가를 통해 변수가 null 또는 undefined인지 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690426262456&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var str = '';

var length = str?.length;
console.log(length); // 0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 옵셔널 체이닝 연산자 '?.'는 좌항 피연산자가 flase로 평가되는 Falsy 값이라도&lt;b&gt; null 또는 undefined가 아니면 우항의 프로퍼티 참조를 이어간다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3) null 병합 연산자 ( ?? )&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES11에서 도입된 null 병합 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다. null 병합 연산자 ??는 변수에 기본값을 설정할 때 유용하다.&lt;/p&gt;
&lt;pre id=&quot;code_1690426880466&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var foo = null ?? 'default string';
console.log(foo); // &quot;default string&quot;

var boo = '' || 'default string';
console.log(foo); // 'dafault string'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;null 병합 연산자 ??는 변수에 기본값을 설정할 때 유용하다. null 병합 연산자 ??가 도입되기 이전에는 논리 연산자 ||를 사용한 단축 평가를 통해 변수에 기본값을 설정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리 연산자 ||를 사용한 단축 평가의 경우 좌항의 피연산자가 false로 평가되는 Falsy 값이면 우항의 피연산자를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Falsy 값인 0이나 ''도 기본값으로서 유효하다면 예기치 않은 동작이 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;모던자바스크립트.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nWfN0/btspdsqxRh1/2oJJo3c8YgUTKN5C9DwZK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nWfN0/btspdsqxRh1/2oJJo3c8YgUTKN5C9DwZK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nWfN0/btspdsqxRh1/2oJJo3c8YgUTKN5C9DwZK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnWfN0%2FbtspdsqxRh1%2F2oJJo3c8YgUTKN5C9DwZK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;422&quot; height=&quot;578&quot; data-filename=&quot;모던자바스크립트.png&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;해당&amp;nbsp;&lt;/span&gt;글은&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&amp;nbsp;[&lt;/span&gt;모던 자바스크립트&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;&amp;nbsp;Deep Dive - 저자 이응모] 도서의 내용을 정리한 글입니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <category>옵셔널 체이닝 연산자</category>
      <category>자바스크립트 null 병합</category>
      <category>자바스크립트 논리합 연산자</category>
      <category>자바스크립트 옵셔널 체이닝</category>
      <category>자바스크립트 타입변환</category>
      <author>예스현</author>
      <guid isPermaLink="true">https://yeshyun.tistory.com/53</guid>
      <comments>https://yeshyun.tistory.com/53#entry53comment</comments>
      <pubDate>Thu, 27 Jul 2023 12:12:55 +0900</pubDate>
    </item>
  </channel>
</rss>